• ベストアンサー

エクセルVBAでAutoShape削除

シートからオートシェープの星型と線を削除するためのマクロですが、以下でうまく行きます。 Sub SAKUJO() For Each s In ActiveSheet.Shapes If s.Type = msoLine Or s.AutoShapeType = msoShape5pointStar Then s.Delete Next End Sub 質問は、線と星型を他のオートシェープと選別するために、線は「Type」、星型は「AutoShapeType」と異なる選別方法を別々に指定しなければならないのかということです。そもそも「Type」と「AutoShapeType」は何が違うのでしょう? 両方を同じように「Type」か「AutoShapeType」あるいは他の方法で指定する方法はないのでしょうか?

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

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.5

こんにちは。KenKen_SP です。 補足というより、蛇足コメントです、、、 Wendy02 さんご提示の通り、Name で識別するのが最も手っ取り 早そうですね。 一意の名前についてですが、このような場合次の方法がいいと思 います。 シェープをコードで書いた時点で既に Excel が一意の名前を付与 しています。後で処理し易くするために、その名前に接頭辞か 接尾辞を加えます。 With ActiveSheet.Shapes.AddShape _   (msoShape5pointStar, LP, TP, W, H)   .Name = "5pointStar_" & .Name End With この方法ですと、同名は発生しません。 これを再処理する場合は Shapes コレクションか DrawingObjects コレクションでループさせて Name プロパティの値を Like 演算子 で比較するか、InStr 関数を使います。 Like 演算子による方法は既に Wendy02 さんが示されてますので、 InStr 関数による方法です。 For Each shp In ActiveSheet.DrawingObjects   If InStr(1, shp.Name, "5pointStar_") > 0 Then     shp.Delete   End If Next shp ご参考までに。

merlionXX
質問者

お礼

いつもお世話様です。 > .Name = "5pointStar_" & .Name すばらしい! これなら連番の振り方でなやむ必要がなくなりました。 ありがとうございます。

その他の回答 (5)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

merlionXX さん、KenKen_SP さん、こんにちは、Wendy02 です。 回答とは直接関係がありませんが、私は、自分のこの関連コードに関しては、未だ、解明できていないところがあります。解決せずに、ちょうど1年になろうとしています。 merlionXXさんは、お分かりになっていると思いますが、いわゆる、オートシェイプを量産して、削除してということを繰り返していくうちに、いわゆる、.name の「オブジェクト・ネーム」の枝番が、更新もされずに、インクリメンタルに増えていきますね。 その点で、私は、自分でオートシェイプを使ったコードに対して不安を覚えました。 仕事で毎日、私の作ったシートとコードで、オートシェイプの生成と削除を繰り返したら、年間では、1万では済まないはずで、通常使用で、最低1年間ぐらいのブックの安全が確保されるか、分からなくなりました。そこで、全面的にコードの内容を換えたことがあります。 それに比べて、シート名の枝番は、再起動すれば、更新されますね。また、自動記録マクロのMacro名も更新されます。開いたまま、Add-Deleteを繰り返さなければ、ほぼ大丈夫です。ですが、オートシェイプだけは出来ません。 削除して、再起動すれば、本当に、全部がクリアになっているならよいのですが、このように、何かが残っているとなると、果たして、Add-Delete を繰り返して、大丈夫かなっていうのが、私の懸案の問題です。 だから、オートシェイプは、使いまわし出来るなら、使いまわししていこう、というのが、現在の私のVBAにおいての考え方です。 まだ、解決には至っていません。 分かっているのは、 \ApplicationData\Microsoft\Office\Recent フォルダの .lnk ファイルには、それは存在していません。レジストリだとしたら、それも、まずいはずです。 #4 の'オートシェイプを作る のコードは、現れないようなことはありませんよね。ところが、繰り返しをすると、図形が現れなくなります。そこで、コードの最後に、Application.ScreenUpdating = True はいれないといけないのですが、何かがヘンだなって思います。 私のPC固有の現象かもしれませんが、他の方が、そうしたコードで図形が出ないといわれたことがありますので、それは間違いないと思っています。

merlionXX
質問者

お礼

補足に書いた件、新しい質問としてみます。 ありがとうございました。

merlionXX
質問者

補足

KenKen_SP さん、Wendy02 さん、おふたりには本当にいつもお世話になります。 > name の「オブジェクト・ネーム」の枝番が、更新もされずに、インクリメンタルに増えていきますね。 はい、じつはこれは次の質問にしようと思っていたんです。 どこまでも増えていくけど、大丈夫なんですか?って。 テスト用のコードも作ってあります。 現在、28000番まできていますが、いまのところ大丈夫です。 For n = 1 To 100 の数値を増やして、いっぺんに何万もやってみようかとも思いましたが、1000を超えると、極端に動きがおそくなり、やがて固まってしまいます。 Sub test() With Application .WindowState = xlMaximized .DisplayFormulaBar = False .Caption = "☆TEST中☆" End With With ActiveWindow .WindowState = xlMaximized .DisplayWorkbookTabs = False .DisplayGridlines = False .DisplayHeadings = False End With For Each myCB In Application.CommandBars myCB.Enabled = False Next myCB Randomize With ActiveSheet .Cells.Interior.ColorIndex = 1 CL = Int((50 * Rnd) + 1) L1 = Int((700 * Rnd) + 20) H1 = Int((450 * Rnd) + 20) Set SA = .Shapes.AddShape(msoShape5pointStar, L1, H1, 25, 25) SA.Name = "Merlion_" & SA.Name SA.Fill.ForeColor.SchemeColor = CL For n = 1 To 100 CL = Int((50 * Rnd) + 1) L2 = Int((650 * Rnd) + 20) H2 = Int((450 * Rnd) + 20) On Error GoTo line SA.Top = H2 - SA.Width / 2 SA.Left = L2 - SA.Height / 2 SA.Fill.ForeColor.SchemeColor = CL Set SL = .Shapes.AddLine(L1, H1, L2, H2) SL.Name = "Merlion_" & SL.Name Application.StatusBar = SL.Name SL.line.Weight = 0.75 SL.line.ForeColor.SchemeColor = CL L1 = L2 H1 = H2 Next SA.ZOrder msoBringToFront SA.line.Visible = True SA.line.ForeColor.SchemeColor = CL For i = 1 To 800 Step 60 SA.Rotation = i / 10 SA.line.Weight = i DoEvents Next line: For Each s In .Shapes If s.Name Like "Merlion_*" Then s.Delete Next .Cells.Interior.ColorIndex = xlNone End With With Application .DisplayFullScreen = False .DisplayFormulaBar = True .DisplayStatusBar = True .Caption = "" End With With ActiveWindow .DisplayWorkbookTabs = True .DisplayGridlines = True .DisplayHeadings = True End With For Each myCB In Application.CommandBars myCB.Enabled = True Next myCB End Sub

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

merlionXX さん、こんにちは。 一応、サンプルは提示しておきます。 # 星は、Regtangle Sub ShapesTypeName() Dim shp As Object For Each shp In ActiveSheet.DrawingObjects   MsgBox TypeName(shp) Next End Sub >一回の操作で何百個も図形が生成され、削除されるんです。だからいちいち一意の名前なんて付けられないんです。 'オートシェイプを作る Sub AddshapePrc() With ActiveCell   Lf = .Left: Tp = .Top: Ht = .Height   FirstLocation = 0.5 + Ht * 2   For i = 0 To 10    With ActiveSheet.Shapes.AddShape _     (msoShapeOval, FirstLocation + Lf, Ht * i + Tp, Ht, Ht)     .Line.ForeColor.SchemeColor = 10     .Visible = True     .Name = "Ov" & i + 1  'ここの部分    End With   Next  End With End Sub '削除方法 Sub DelshapePrc() For Each shp In ActiveSheet.Shapes   If shp.Name Like "Ov*" Then     shp.Delete   End If Next End Sub

merlionXX
質問者

お礼

お礼がおそくなり、すみません。 なるほど~っ!! .Name = "Ov" & i + 1  ですかあ。 これならいくつでも名前が付けられますね。 ありがとうございました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

merlionXXさん、こんにちは。 すみません。あまり、私は、星などは、使ったことがなかったので、出来ると思い込んでいました。先ほど、TypeName でもとってみたのですが、星は、Rectangle でした。 そうすると、既存のものに対しては、AutoShapeType の組み込み定数以外にはなさそうですね。 逆にいうと、私の実際のコードでは、先に、オートシェイプを作る際に、オートシェイプの名前に一意の名前をつけています。そうすれば、見失うことがありませんから。

merlionXX
質問者

お礼

> オートシェイプの名前に一意の名前をつけています。 ありがとうございます。 でもうごきの激しいのを作っているので、一回の操作で何百個も図形が生成され、削除されるんです。だからいちいち一意の名前なんて付けられないんです。

merlionXX
質問者

補足

何度もありがとうございます。 そうですよね、ふつうVBAで星型なんて使いませんよね(笑) TypeNameでとる? Cells(n, "G").Value = TypeName(S)とやってみたら、すべて「Shape」でしたが、どうやって取得したのでしょうか? > 星は、Rectangle ええっ?!Rectangleって四角形って意味ですよ?!

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんにちは。 >そもそも「Type」と「AutoShapeType」は何が違うのでしょう? >両方を同じように「Type」か「AutoShapeType」あるいは他の方法で指定する方法はないのでしょうか? 私の経歴はそんなに長くないのですが、AutoShape自体が、時代を経て、コレクション化したのではないでしょうか? Type で取れる「MsoShapeType」クラスのというのは、AutoShape、Chart、Comment、OLEObject, FormControl などに、Lineもあって、もともと別な存在だったわけです。 それを統合して、AutoShape にしたのであって、上記のAutoShape の個別のAutoShape コレクションは、図形のひとまとめにしたもので、その中に、AutoShapeType があります。 別の方法といっても、DrawingObjectのShapeRange では、同じように、TypeとAutoShapeType とになるので、同じことです。だから、おなじ プロパティで選別する方法は、プロパティの name をLike で取る以外は、ないのではないかと思います。name は、Object名として、マクロ以外には変更は出来ませんから、ある程度は、有効だ思います。

merlionXX
質問者

お礼

Wendy02さん、いつもお世話様です。 くだらない質問ですみません。

merlionXX
質問者

補足

Nameで区別できればいいと思い、以下のマクロでNameを取得してみました。 Sub s_name() n = 5 For Each s In ActiveSheet.Shapes n = n + 1 Cells(n, "D").Value = s.Name Cells(n, "E").Value = s.Type Cells(n, "F").Value = s.AutoShapeType Next End Sub ところが、これでは線は「Line ###」、ワードアートは「WordArt ###」、フォームからの挿入のものは「Check Box ###」、「Option Button ###」と区別できるのですが、図形は星型も月型もハート型もみな「AutoShape ###」で区別がつかないんです。(四角形は「Rectangle ###」、円弧は「Arc ###」、楕円は「Oval "###」で区別できたのですが、それ以外はみな「AutoShape ###」です。)

  • moooon
  • ベストアンサー率26% (26/98)
回答No.1

しらべてみたら、線のAutoShapeTypeは-2でした。 星は92でした。 だから、こうやったら両方とも削除できました。 For Each s In .Shapes Select Case s.AutoShapeType Case 92, -2 s.Delete End Select Next

merlionXX
質問者

お礼

ありがとうございます。 これはいい!と思って試したら、星と線だけではなく、ワードアートやフォームから入れたボタンやチェックボックス等も削除されてしまいました。 フォームから挿入したものもAutoShapeTypeは-2のようです。

関連するQ&A

  • エクセルVBAでオートシェープを識別して削除したいのです・・・

    エクセルシートにたくさん貼り付けた画像を一度に削除するため、下記のようなマクロを作成しました。 しかし、これでは「テキストボックス」や「→」のようなオートシェープも全部消えてしまいます。 画像データ(図)だけを認識して消すにはどうすればよいのでしょうか? Sub sakujo() Dim Myshape As Shape For Each Myshape In ActiveSheet.Shapes If Myshape.Type <> msoFormControl Then Myshape.Delete End If Next End Sub

  • VBAについて教えてください。

    VBAについて質問です。 シート1(元払)があり、そのシート内のオートシェイプを消す式が下記の式で 可能なのですが、別シートのオートシェイプも同時に消す場合はどのようにすれば良いか 教えてください。   Sheets("元払").Select Dim sh As Shape For Each sh In ActiveSheet.Shapes If sh.Type = msoAutoShape Then sh.Delete End If Next sh

  • エクセルVBA オートシェイプを操作したいです

    エクセルでセルの入力内容によって楕円をオートシェイプで出現させたいと思います。 http://oshiete1.goo.ne.jp/qa809742.htmlで見つかったものを参考にし、 Private Sub worksheet_Activate() Dim Shp As Shape Set P11 = Range("P11") If P11 Is Nothing Then Exit Sub If P11.Value = 1 Then For Each Shp In ActiveSheet.Shapes If Not Application.Intersect(Shp.TopLeftCell, _ Range("N14:N15")) Is Nothing Then Shp.Delete End If Next Shp With ActiveSheet.Range("N14:N15") ActiveSheet.Shapes.AddShape(Type:=msoShapeOval, _ Left:=.Left,TOP:=.TOP,Width:=.Width,Height:=.Height).Select Selection.ShapeRange.Fill.Visible = msoFalse End With Range("N14").Select Else For Each Shp In ActiveSheet.Shapes If Not Application.Intersect(Shp.TopLeftCell, _ Range("N14:N15")) Is Nothing Then Shp.Delete End If Next Shp End If If P11.Value = 2 Then For Each Shp In ActiveSheet.Shapes If Not Application.Intersect(Shp.TopLeftCell, _ Range("N16")) Is Nothing Then Shp.Delete End If Next Shp With ActiveSheet.Range("N16") ActiveSheet.Shapes.AddShape(Type:=msoShapeOval, _ Left:=.Left, TOP:=.TOP, Width:=.Width, Height:=.Height).Select Selection.ShapeRange.Fill.Visible = msoFalse End With Range("N16").Select Else For Each Shp In ActiveSheet.Shapes If Not Application.Intersect(Shp.TopLeftCell, _ Range("N16")) Is Nothing Then Shp.Delete End If Next Shp End If End Sub とつなげて見ました。 動くには動くのですが、データ元のセルがP11からT30と100セルあり、さらにP11に入力されるデータが1,2,3,4の4種類、AQ11に5,6,7,8,9の5種類などと、ばらばらです。 P11に1が入力されるとN14:N15(結合されています)に円が入り、2が入力されるとN16に円が入る。 Q11に5が入力されるとR13に円が入り、6が入力されるとR14:R15に円が入る・・・・のようにしたいのです。 一生懸命、セルNo.を打ち込んでいたら、 「コンパイルエラー:プロシージャが大きすぎます」とエラーが出てしまいました。 ループさせればよいのだろうと試してみたのですが、元のセルの指定方法や、オートシェイプの出現させるせるの指定方法がわかりません。 どのようにすれば、データー元の範囲を指定して、それに対応したセルにオートシェイプを出現させる事が出来るようになるでしょうか。 お知恵を貸していただけないでしょうか。よろしくお願い致します。

  • EXCEL VBA これであっていますか?

    エクセルに地図を貼り付け、その中のある地点Aから半径1キロ、2キロ、3キロといった具合に円を描いています。ある地点B、Cも同様に円があります。セルに“A” と入力した際に該当する地点の円(1キロ、2キロ、3キロの3種類)を赤く表示し、終了すると円が消える(線なしに変わる)ようにするために以下のようなVBAを組みました。が、円が2つしか赤くならなかったり、 ばあいによっては「インデックスが境界を超えています」とエラーが出たりします。 どうしたら良いか教えてください。 Sub iro() Dim i As Variant i = InputBox("表示する地点を指定してください", "地点指定") If i = "A" Then ActiveSheet.Shapes(1).Select ActiveSheet.Shapes(2).Select ActiveSheet.Shapes(3).Select Replace:=False hyoji MsgBox "表示を終了してよろしいですか", vbOKOnly ActiveSheet.Shapes(1).Select ActiveSheet.Shapes(2).Select ActiveSheet.Shapes(3).Select Replace:=False modosu ElseIf i = "B" Then ActiveSheet.Shapes(4).Select ActiveSheet.Shapes(5).Select ActiveSheet.Shapes(6).Select Replace:=False hyoji MsgBox "表示を終了してよろしいですか", vbOKOnly ActiveSheet.Shapes(4).Select ActiveSheet.Shapes(5).Select ActiveSheet.Shapes(6).Select Replace:=False Else MsgBox "指定した地点がありません", vbOKOnly End If End Sub Sub hyoji() Selection.ShapeRange.Line.Visible = msoTrue '「線なし」に設定されている場合、線を表示 Selection.ShapeRange.Line.ForeColor.SchemeColor = 10 Range("A1").Select End Sub Sub modosu() Selection.ShapeRange.Line.Visible = msoFalse '「線なし」に設定 Range("A1").Select End Sub

  • エクセルVBAの線オブジェクト一括選択法

    エクセル2000VBAの初心者です。よろしくお願いいたします。 QNo.2268830に対するhana-hana3さんの回答にあった参照リンクに、 >●オートシェイプの円形の図だけを選択するには? >アクティブシートのオートシェイプで円形の図だけを選択する例です。 >Sub 円形のオートシェイプを全て選択() > Dim C As Shape > For Each C In ActiveSheet.Shapes >  If C.AutoShapeType = msoShapeOval Then C.Select False > Next C >End Sub がありました。これで、円形(msoShapeOval)や四角形(msoShapeRectangle)はうまく選択することが出来たのですが、オートシェイプで描いた線(AddLineで)を選択することが出来ません。 上記プログラムで、msoShapeOvalをLineに変えたり、いろいろしてみたのですが、分かりません。 どなたがご教授いただければ助かります。

  • VBA オートシェイブや図を選択したいのですが

    VBAでシート上にある全てのオートシェイブや図を選択したいのですが どのようにすればいいでしょうか? 手作業でなら、CTRL+Gでオブジェクトを選択すればできますがVBAで行いたいです。 Sub test() Dim s As Shape For Each s In ActiveSheet.Shapes s.Select Next End Sub をしても、一つずつしか選択できません。 全てを選択状態にしたいです。

  • VBA 図形の削除

    以下のようなコードにおいて、図名を指定するのではなく、図の種類を指定して削除したいのです。 テキストボックスを消す グラフを消す オートシェイプを消す などなど、オブジェクトの種類を指定して消すようにしたいのですが、どうすれば良いですか? Sub 指定図形削除()  図名=”削除したい図形名”  For Each zu In ActiveSheet.Shapes   If zu.Name = 図名 Then    zu.Delete    Exit For   End If  Next End Sub

  • エクセルVBAの構文についての質問です

    ちょっと前から勉強しはじめた超超初心者なんですが、オブジェクトやプロパティといった概念がちょっと理解できないでくるしんでいます 1、 Sub 図形非表示() ActiveSheet.Shapes("図形").Visible=False End Sub これは本にのっていた例文でアクテブシートの「図形」という名前のオートシェイプを非表示にする文なのですが本には「Visible プロパティ」 「Shapes プロパティ オートシェイプを返します」とありますがこれはつまり「Shapesプロパティ自体がオブジェクトになっている」ということなのでしょうか?「Shapes プロパティ」とかいてあるのでただのプロパティなのではないか???とおもってしまうのですが・・・ 2、 1と同じ感じなのですが Sub ワークシートに色を設定()   Worksheets("メニュー").Cells.Interior.ColorIndex=11 End Sub もInteriorプロパティ自体がオブジェクトになっているのでしょうか?? だとしたら全てのプロパティもオブジェクトになれるのでしょうか? 是非どなたか教えてください、よろしくお願いします

  • エクセルVBAでLineの一括処理

    ワークシート上に配置した複数のオートシェープの線(Lines)に対し、一括して太さと色を変えるにはどのようなコードになるのでしょうか? 勿論以下のTEST01のように名前で指定すれば可能なのですが、TEST02のような全てのLineということはできないのでしょうか? Sub Test01() With ActiveSheet.Shapes.Range(Array("Line 259", "Line 260")) .line.Weight = 1.75 .line.ForeColor.SchemeColor = 13 End With End Sub ↓実行時エラーとなる Sub Test02() With ActiveSheet.Lines .line.Weight = 2.5 .line.ForeColor.SchemeColor = 10 End With End Sub

  • エクセルVBAで画像を貼り付ける座標設定方法は?

    Sheets("Sheet1")に貼り付けたJ-pegの画像(=シンボルマーク)を別なシートに貼り付けるのは下記のVBAで出来ました。ただ、これでは貼り付け先のシートのセルK12が、貼り付け元のK12と同じ位置でないと思った場所に張り付きません。 そこでセルで場所を指定するのではなく、座標のようなもので指定する方法はないものかと考えた次第です。 オートシェイプなどは座標指定で作成できるのですが、J-pegのような画像はどうすればいいのでしょうか? Sub TEST() Sheets("FACE").Shapes("シンボルマーク").Copy ActiveSheet.Range("K12").Select ActiveSheet.Paste End Sub

専門家に質問してみよう