Excel VBAオブジェクト(図形)の保護

このQ&Aのポイント
  • Excel VBAのオブジェクト(図形)の保護について質問させて頂きます。
  • 予約表の図形の矢印を動かせないようにし、名前と*を消すと矢印が消えるようにしたいです。
  • 具体的なコーディング方法について教えてください。
回答を見る
  • ベストアンサー

Excel VBAオブジェクト(図形)の保護

Excel VBAのオブジェクト(図形)の保護について質問させて頂きます。 現在、社内の打合せコーナーの予約表をExcel VBAで作成しておりまして、予約したい開始時間に名前、終了時間に*を入れると、図形の矢印が描画される様になっています。(画像をご参照) しかし、この矢印が動かせてしまう為、開始時間の名前と終了時間の*が入っている間は動かせない様にし、名前と*を消すと矢印が消える様にしたいのですが、どの様にコーディングすれば実現できるでしょうか? ご存知の方、ご教示宜しくお願い致します。 ↓は予約表の現在のVBAのコードです。 Private Sub Worksheet_Change(ByVal Target As Range) Dim stflg As String Dim sth As Long Dim stw As Long Dim edh As Long Dim edw As Long Const maxw = 26 Const maxh = 66 Const cellh = 13.5 Const cellw = 33.85 '入力チェック With ActiveSheet For i = 6 To maxh Step 2 stflg = "" For j = 3 To maxw If .Cells(i, j).Value <> "" Then If .Cells(i, j).Value = "*" Then If stflg = "" Then MsgBox "入力内容が誤りです" .Cells(i, j).Select Exit Sub Else stflg = "" End If Else stflg = "1" End If End If Next j Next i End With '矢印を全て削除する For Each oShape In ActiveSheet.Shapes If oShape.Type = msoLine Then oShape.Delete Next With ActiveSheet For i = 6 To maxh Step 2 stflg = "" For j = 3 To maxw If .Cells(i, j).Value <> "" Then If .Cells(i, j).Value = "*" Then edh = ((i - 2) * cellh) + (cellh / 1.6) edw = 60 + ((j - 2) * cellw) With .Shapes.AddLine(stw, sth, edw, edh).Line .ForeColor.SchemeColor = 0 .EndArrowheadStyle = msoArrowheadStealth .Weight = 1.5 End With stflg = "" Else If stflg = "" Then sth = ((i - 2) * cellh) + (cellh / 1.6) stw = 60 + ((j - 3) * cellw) stflg = "1" Else edh = ((i - 2) * cellh) + (cellh / 1.6) edw = stw + cellw With .Shapes.AddLine(stw, sth, edw, edh).Line .ForeColor.SchemeColor = 0 .EndArrowheadStyle = msoArrowheadStealth .Weight = 1.5 sth = ((i - 2) * cellh) + (cellh / 1.6) stw = 60 + ((j - 3) * cellw) End With End If End If End If If j = maxw And stflg <> "" Then edh = ((i - 2) * cellh) + (cellh / 1.6) edw = stw + cellw With .Shapes.AddLine(stw, sth, edw, edh).Line .ForeColor.SchemeColor = 0 .EndArrowheadStyle = msoArrowheadStealth .Weight = 1.5 End With End If Next j Next i End With End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

もう見ていないかな? アイデアの提示だけではなんなので、自分なりのコードで試してみました。 偶数行に、値を入れ、次いで右方のセルに「*」を入れると、一つ上の行に矢印を引きます。 このときOnActionでマクロを仕込んでおきます。 引いた矢印は保護が掛けられて消せません。(簡便のためセルのデータの保護等は考慮していません) 矢印下のスタート位置のセルの値と、終了位置の「*」を消した後、矢印をクリックすると、仕込んで置いたマクロが動いて保護が外れます。下記コードではついでに消してしまっています。 ご希望の仕様と異なりますが、複雑なイベントマクロを読み解いて、更に複雑な動作を組み込む元気がありませんので、参考になる部分があればご活用下さい。(Changeイベントで全図形をスキャンして、TopLeftCell,BottomRightCellの合致をみて図形を特定し、保護を外して削除するといった事は可能と思います) '☆シートモジュール Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long Dim myColumn As Long Dim startCell As Range Dim myShape As Shape If Target.Cells.Count > 1 Then Exit Sub If (Target.Row Mod 2) > 0 Then Exit Sub If Target.Value <> "*" Then Exit Sub For i = 1 To Target.Column - 1 If Target.Offset(, -1 * i).Value <> "" And Target.Offset(, i).Value <> "*" Then Set startCell = Target.Offset(, -1 * i) Exit For End If Next i Me.Unprotect If Not startCell Is Nothing Then Set myShape = Me.Shapes.AddLine(startCell.Left, startCell.Top - startCell.Height / 2, Target.Left + Target.Width, Target.Top - startCell.Height / 2) '.Line myShape.OnAction = "shapeUnprotect" With myShape.Line .ForeColor.SchemeColor = 0 .EndArrowheadStyle = msoArrowheadStealth .Weight = 1.5 End With End If Me.Protect DrawingObjects:=True End Sub '☆標準モジュール Sub shapeUnprotect() Dim myShape As Shape Set myShape = ActiveSheet.Shapes(Application.Caller) 'なぜかBottomRightCellは矢印を引いた最終セルの一つ右のセルになっているので-1している If myShape.TopLeftCell.Offset(1, 0).Value = "" And myShape.BottomRightCell.Offset(1, -1).Value = "" Then ActiveSheet.Shapes(Application.Caller).Locked = msoFalse 'ついでに消してしまう場合 ActiveSheet.Shapes(Application.Caller).Delete End If End Sub

hellohello21
質問者

お礼

返信が遅くなりまして申し訳ございません。 ご回答有難うございます! ご丁寧にアイディアをご提示下さいまして、感謝致しております。 是非ご参考にさせて頂きたいと思います!

関連するQ&A

  • VBAでの質問

    お世話になります。 下記の記述で、「←」の矢印の記述で、 Cells.(5,2)がブランクでなければ、 「→」から進めたいのですが、 どの様に記述すれば宜しいでしょうか ご教示お願いします。 Sub 表記入() Dim Data As Range Dim i As Integer Dim j As Integer Dim k As Integer Set Data = Sheets("集計").Range("A2").CurrentRegion j = 16 k = 0 With Sheets("表") For i = 3 To Data.Rows.Count If Data.Cells(i, 51) <> "" Then .Cells(5, 2) = Data.Cells(i, 3)  ← .Cells(5, 7) = Data.Cells(i, 4) → .Cells(j, 2) = Data.Cells(i, 10) .Cells(j, 6) = Data.Cells(i, 11) & Data.Cells(i, 12) .Cells(j, 14) = Data.Cells(i, 51) Else End If k = k + 1 If k = 10 Then j = j + 18 k = 0 Else j = j + 1 End If End If Next i End With End Sub

  • エクセルVBAの繰り返し処理の質問

    C列にある項目とG列にある項目を比較して、 一致し、H列にある数字が10以上ならば、B列にフラグ1を立てる という処理を行いたいんですが、 下記ぐらいまでしか作れず、うまくいきません・・・ Sub フラグを立てる処理() Dim i As Integer Dim j As Integer Dim k As Integer i = 1 j = 1 Do j = j + 1 Do i = i + 1 If Cells(j, 8) > 9 Then Cells(i - 1, 4) = 1 End If Loop Until Cells(i, 3) <> Cells(j, 7) Or Cells(i, 3) = "" Loop Until Cells(j, 7) = "" End Sub わかる方がいらっしゃいましたら、お願いします。

  • ExcelのVBAで質問です。

    以下のようなシートがあります。 A列  B列  C列  D列  E列  F列  G列  H列 NO  名前  確認 日付1 日付2  確認 日付1 日付2 6行目からデータを入れる予定です。 C列には○印を入力します。 C列~E列までデータが入った行は、 F列~H列まで同じ処理をします。 (セルの背景色を変えます。) 以後同じことを列方向で繰り返します。 以下のようなVBAを組みましたが、 ○の個数を数える部分でエラーがでます。 Private Sub Worksheet_Change(ByVal Target As Range) Dim staff As String Dim kakunin As String Dim date1 As Date Dim date2 As Date Dim i As Long Dim j As Long Dim cnt As Long '100件分ループ For i = 6 To 105 '○の数をカウント cnt = WorksheetFunction.CountIf(ActiveSheet.Range(Cells(i, 2), Cells(i, 256)), "○") 'jとは確認の列番号のこと j = 3 * cnt staff = Cells(i, 2) kakunin = Cells(i, j) date1 = Cells(i, j + 1) date2 = Cells(i, j + 2) 'スタッフ名が入力されたら If staff = "" Then Range(Cells(i, j), Cells(i, j + 50)).Interior.ColorIndex = 15 Else Cells(i, j).Interior.ColorIndex = xlNone '○が入力されたら If kakunin = "○" Then Range(Cells(i, j + 1), Cells(i, j + 2)).Interior.ColorIndex = xlNone Else Range(Cells(i, j + 1), Cells(i, j + 2)).Interior.ColorIndex = 15 End If If Cells(i, j + 1) <> "" And Cells(i, j + 2) <> "" Then Cells(i, j + 3).Interior.ColorIndex = xlNone End If End If Next i End Sub ご教授いただけたら、幸いです。 よろしくお願いいたします。

  • EXCEL VBA2010 MsgBox

    Sub 重複() Dim i As Long, j As Long For i = 6 To 500 For j = 3 To 3 If WorksheetFunction.CountIf(Range("C6:C500"), Cells(i, j)) > 1 Then Cells(i, j).Interior.ColorIndex = 6 End If Next j Next i End Sub このVBAに重複が何件ありますよというメッセージを出したいです。 MsgBoxの入れ方を教えてください。

  • エクセルvbaで、同じ番号の請求書の金額をまとめる方法 2

    エクセルvbaで、同じ番号の請求書の金額をまとめる方法 2 すみません、前回質問して良い回答をいただいたのですが、こちらの手違いで 用件がひとつぬけていました。 A    B     I    K    L     M 11/5 B575    3000  7500 5000 13500 11/5 B575    4500      8500 11/6 B578    3000   3000 4000 40000 上記のように A日付 B請求書番号 I金額 K金額合計 が入力されています。 (IからKにとんでいるのは間違いではありません) M列にも同じようにL列の同じ請求書番号の金額の合計をセルを結合して中央揃えで表示したいのです。 以前のプログラムに加筆することで可能になるでしょうか。 下に貼り付けます。 Dim i As Long, j As Long Dim buf As Variant, ret As Double For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row buf = Val(Cells(i, 9).Value) '修正 If Cells(i, 2).Value <> Cells(i + 1, 2).Value Then If j = 0 Then j = i With Range(Cells(j, 11), Cells(i, 11)) .MergeCells = True .HorizontalAlignment = xlCenter .VerticalAlignment = xlCenter End With If buf + ret > 0 Then Cells(j, 11).Value = buf + ret End If Cells(j, 11).NumberFormat = "#,##0" ret = 0: j = 0 Else If j = 0 Then j = i ret = buf + ret End If Next ''合計欄 'With Cells(i, 4) ' .NumberFormat = "#,##0" ' .HorizontalAlignment = xlCenter ' .Formula = "= SUM(R1C:R[-1]C)" 'End With ご多忙の中申し訳ございませんがよろしくお願いします。

  • Excel VBAライフゲーム

    ExcelのVBAでライフゲームを作りたいのですが、次のプログラムの途中以降がわかりません。 もしよろしければ、このつづきの簡単な実行できるVBAライフゲームを教えてください。 続きのプログラムを教えていただけたら幸いです。 Option Explicit Const ALIVE As Integer = 1 Const DEAD As Integer = 0 Const SIZE As Integer = 19 Const Tmax As Integer = 100 Dim C(SIZE, SIZE) As Integer Sub LifeGame() Dim InitRate As Single Dim T As Integer Dim N As Integer Dim Cnext(SIZE, SIZE) As Integer Dim I As Integer, J As Integer InitRate = -1 Do While InitRate < 0 Or 1 < InitRate Loop For I = 0 To SIZE For J = 0 To SIZE If Rnd() < InitRate Then C(I, J) = ALIVE Else C(I, J) = DEAD End If Next J Next I For T = 1 To Tmax For I = 0 To SIZE For J = 0 To SIZE If C(I, J) = ALIVE Then Cells(I + 1, J + 1).Value = "■" Else Cells(I + 1, J + 1).Vallue = "" End If Next J Next I For I = 0 To SIZE For J = 0 To SIZE N = Count(I, J) Next J Next I For I = 0 To SIZE For J = 0 To SIZE C(I, J) = Cnext(I, J) Next J Next I Next T End Sub Function Count(I As Integer, J As Integer) As Integer End Function

  • やはり図形のクリアで実行時エラー1004

     図形を二行三列で一枡とし図形を貼り付けていますが、どうしても実行時エラー 「1004」が出て図形のクリアができません。(尚、四角形は枠線上にあります。) 対処法がありましたらお願いします。 Windows7・SP1 Office2010 Sub 図形の貼付け() Dim i As Integer Dim j As Integer For i = 10 To 43 Step 2 For j = 9 To 99 Step 3 Select Case Cells(i, j).Value Case 1: ActiveSheet.Shapes("四角形1").Select Selection.Copy Cells(i + 1, j + 1).Select ActiveSheet.Paste Case 2: ActiveSheet.Shapes("四角形2").Select Selection.Copy Cells(i + 1, j).Select ActiveSheet.Paste Case 4: ActiveSheet.Shapes("四角形3").Select Selection.Copy Cells(i + 1, j + 1).Select ActiveSheet.Paste Case 5: ActiveSheet.Shapes("四角形3").Select Selection.Copy Cells(i + 1, j + 2).Select ActiveSheet.Paste Case 6: ActiveSheet.Shapes("円1").Select Selection.Copy Cells(i, j).Select ActiveSheet.Paste End Select Next Next End Select End Sub Sub 図形のクリア() Dim myRng As Range Set myRng = Range("I10:CW43") Dim n As Integer, sp As Variant For n = ActiveSheet.Shapes.Count To 1 Step -1 Set sp = ActiveSheet.Shapes(n) If Not Intersect(Range(sp.TopLeftCell, sp.BottomRightCell), myRng) Is Nothing  (ここで実行時エラー1004になります。) Then sp.Delete End If Next Set myRng = Nothing End Sub

  • エクセル マクロで引いた線の色設定が戻せない

    エクセルで作成した、出席簿にマクロで 土日などに赤線で罫線の間に縦に オートシェィプ直線を引いています。 次に転出者の欄には、横に線をマクロで引いていますが 色が変えられません。 マクロ終了後もオートシェイプの線色は黒でも 、線を引くと赤のままです。 その線を選択して、色を変えないと 変えられない状態です。 マクロ終了前に、色をリセットする事は出来ませんか? 下記の内容がマクロの一部です。 よろしくお願いします。 If yobi = doyo Or yobi = niti Then Cells(3, 2 + n).Activate If yobi = niti Then With Selection.Font .ColorIndex = 3 End With End If ActiveSheet.Shapes.AddLine(110.25 + 21.75 * (n - 1), 42, 110.25 + 21.75 * (n - 1), 651).Select Selection.ShapeRange.Line.ForeColor.SchemeColor = 10 '10=赤色 End If If yobi = "" Then ActiveSheet.Shapes.AddLine(110.25 + 21.75 * (n - 1), 14.25, 110.25 + 21.75 * (n - 1), 651).Select Selection.ShapeRange.Line.ForeColor.SchemeColor = 8 '8=黒色 End If

  • エクセルVBAでDictionaryオブジェクトについて

    エクセル2000です。 教えてください。 http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_dictionary.html というサイトで  「myDic.Add Cells(i, 1).Value, Cells(i, 2).Value は   myDic(Cells(i, 1).Value) = Cells(i, 2).Value と書くこともできます。 」 という記述を見つけました。 試してみたところ Sub test01() Dim myDic As Object Dim myAr() Set myDic = CreateObject("Scripting.Dictionary") For i = 2 To 7 If Not myDic.exists(Cells(i, 1).Value) Then myDic.Add Cells(i, 1).Value, Cells(i, 2).Value End If Next i myAr() = myDic.Keys MsgBox Join(myAr()) End Sub Sub test02() Dim myDic As Object Dim myAr() Set myDic = CreateObject("Scripting.Dictionary") For i = 2 To 7 myDic(Cells(i, 1).Value) = Cells(i, 2).Value Next i myAr() = myDic.Keys MsgBox Join(myAr()) End Sub 上記2つのマクロは、Keyに関してはまったく同じ働きをするようです。 ところがItemに関しては、Keyが重複した場合、あとから出てきた方に上書きされるようです。 これはtest01では、Keyの重複を排除しているためItemは最初に出たものが残る、test02は重複の場合、無条件でKeyが上書きされ(ても値は変化しないけど)、したがってItemも上書きされるという理解でよろしいのでしょうか? ならば、Itemを気にしない場合、わざわざ If Not myDic.exists(Cells(i, 1).Value) Then myDic.Add Cells(i, 1).Value, Cells(i, 2).Value End If と、3行も費やして重複のチェックをしなくとも myDic(Cells(i, 1).Value) = Cells(i, 2).Value のわずか一行で済むということですよね?

  • Excelの罫線に関するマクロ

    Excelの罫線に関するマクロ 罫線を引き、それを赤くするマクロを作ったのですが、赤罫線の下にもうひとつ罫線が表示されてしまいます。どこを削除すればよいのでしょうか。 ご教示お願いいたします。 Sub 罫線() Dim T1 As Single, L1 As Single Dim T2 As Single, L2 As Single Dim myShp As Shape With Range("c15") T1 = .Top L1 = .Left End With With Range("d14") T2 = .Offset(1, 1).Top L2 = .Offset(1, 1).Left End With Set myShp = ActiveSheet.Shapes.AddLine(L1, T1, L2, T2) ActiveSheet.Shapes.AddLine(L1, T1, L2, T2).Select With Selection.ShapeRange.Line .Visible = msoTrue .Style = msoLineSolid .Weight = 5# .ForeColor.SchemeColor = 10 End With End Sub よろしくお願いします。

専門家に質問してみよう