Excel VBAでオートシェイプのType取得でエラーが発生する理由

このQ&Aのポイント
  • Excel VBAを使用してオートシェイプのTypeを取得する際に、特定の図形(複雑な図形)が数十個存在するとエラーが発生し、Excel自体が強制終了します。
  • 複雑な図形とは、フリーハンドを組み合わせたような絵や人物の顔などを指します。
  • このエラーの原因は特定されておらず、推測や可能性によって対処する必要があります。
回答を見る
  • ベストアンサー

エクセルVBAでオートシェイプのType取得でエラー

シート上に複数のグループ化したオートシェイプがあり、 それを一括して消すマクロを組みました。 その時、シート上のボタンまで消してしまわないようTypeで判断しています。 Dim Sp As Shape For Each Sp In Shapes If Not Sp.Type = 12 Then Sp.Delete End If Next 簡単な図形であれば、数百個でも問題ありません。 また、複雑な図形でも数個であれば正常に動作します。 これが、複雑な図形が数十個になると、 "Tyepメソッドは失敗しました。"とエラーが表示されExcel自体が強制終了します。 1、2回で出ないこともたまにありますが、何度か繰り返しますと確実に出ます。 原因が特定できず困っています。 推測や可能性でもかまいません、どうぞよろしくお願いいたします。 ※複雑な図形とはフリーハンドを組み合わせたような絵です。(人物の顔など) 動作はWindows2000のEXCEL2000で2台 WindowsXPのEXCEL2003で1台でテストしました。

  • ebis
  • お礼率54% (29/53)

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

  • ベストアンサー
  • ja7awu
  • ベストアンサー率62% (292/464)
回答No.2

「Excel自体が強制終了します。」とか、「だいたい3回で落ちてしまいました。」という ことから、試しに Sp.Delete の下に DoEvents を入れると、どうなりますか?

ebis
質問者

お礼

すごいです。 もう、何百個書いても、何度繰り返しても問題ありませんでした。 ありがとうございました。

その他の回答 (1)

  • ja7awu
  • ベストアンサー率62% (292/464)
回答No.1

見た感じですが、Shapes って 何処の? となると思いますが・・・ あと、12 だけでは、分りにくいのでは・・・ まぁ、いいけど・・・  Dim Sp As Shape For Each Sp In ActiveSheet.Shapes   If Not Sp.Type = msoOLEControlObject Then     Sp.Delete   End If Next

ebis
質問者

補足

すみません。説明不足でした。 Sheet1内に記述していた為、省略しておりました。 修正していただいたマクロに変えてみましたが、 やはり落ちてしまいました。 簡単にテストするため以下のようにしました。 Sheet1にボタンを2つ付けて Private Sub CommandButton1_Click() Dim i As Long For i = 1 To 10 Worksheets("Sheet2").Shapes("A").Copy ActiveSheet.Paste Next i End Sub Private Sub CommandButton2_Click() Dim Sp As Shape For Each Sp In ActiveSheet.Shapes If Not Sp.Type = msoOLEControlObject Then Sp.Delete End If Next End Sub そしてSheet2には下手なドラえもんの絵をフリーで描いて、グループ化し、"A"と名前を付けました。 これでボタン1を押して書いて、ボタン2を押して消してを繰り返しますと、だいたい3回で落ちてしまいました。

関連する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

  • オートシェープをグルーピングして動作させたい

    office365 2つのオートシェープをグルーピングして図形を動作させたい 下記で kibanは平行四辺形のオートシェープ yajirushiは右向き矢印のオートシェープ で、それぞれ、ある範囲で左から右に移動を繰り返します。 この2つのオートシェープをグルーピングして 平行四辺形の右側に矢印を配置した状態で、そのグルーピングされた図形の動作を繰り返す様にしたいのですが、 その内容が分からないのでコードで教えていただきたく、よろしくお願いします。 #If Win64 Then Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) #Else ' Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) #End If Sub kiban() shape_delete Dim ws2 As Worksheet Dim i As Integer Set ws2 = Sheets("sheet1") ws2.Shapes.AddShape(msoShapeParallelogram, 2265, 354, 46, 20).Select With Selection.ShapeRange.Fill .Visible = msoTrue .ForeColor.RGB = RGB(0, 176, 80) .Transparency = 0 .Solid End With ws2.Shapes.AddShape(msoShapeParallelogram, 2265, 458, 20, 20).Select ws2.Shapes(ws2.Shapes.Count).name = "kiban" For i = 0 To 30 If i = 30 Then i = 0 End If ws2.Shapes(1).Left = i * 3 + 365 ws2.Shapes(1).Top = 458 Sleep 100 DoEvents Next i ws2.Shapes("kiban").delete End Sub Sub yajirushi() shape_delete Dim ws As Worksheet Dim i As Integer Set ws = Sheets("sheet1") ws.Shapes.AddShape msoShapeRightArrow, 2265, 458, 20, 20 ws.Shapes(ws.Shapes.Count).name = "yajirushi" For i = 0 To 30 If i = 30 Then i = 0 End If ws.Shapes(1).Left = i * 3 + 420 ws.Shapes(1).Top = 458 Sleep 100 DoEvents Next i ws.Shapes("yajirushi").delete End Sub Sub shape_delete() Dim shp As Shape Dim rng As Range Range("P22:CM28").Select If TypeName(Selection) <> "Range" Then Exit Sub For Each shp In ActiveSheet.Shapes '‘ 図形の配置されているセル範囲をオブジェクト変数にセット Set rng = Range(shp.TopLeftCell, shp.BottomRightCell) '‘ 図形の配置されているセル範囲と '‘ 選択されているセル範囲が重なっているときに図形を削除 If Not (Intersect(rng, Selection) Is Nothing) Then shp.delete End If Next End Sub

  • Excel VBAのオートシェイプの名前の取得(?)

    いつもお世話になっております。 ある図形[名前:グループ1](イメージとテキストをグループ化したもの)と ある図形[名前:グループ2](イメージとテキストをグループ化したもの)を コネクター[名前:コネクター1]で接続しています。 (□―□ コンナカンジ・・・) 画面上のどちらかの図形をクリックした時に、 (1)クリックされた図形の名前を取得 (2)クリックされた図形に繋がっているコネクタの情報を取得、 (3)さらにそのコネクタの接続先の図形の名前を取得する ・・・というようなVBAのプログラムを組んでいるのですが・・・、 (1)(クリックされたオートシェイプの名前を取得) Dim objShape As Shape Dim ShapeName as string Set objShape = ActiveSheet.Shapes(Application.Caller) ShapeName = objShape.name (2)(繋がっているコネクタの情報を取得) ※正確には画面上の全シェイプをチェックしコネクタなら配列に格納 For Each sh In ActiveSheet.Shapes 'コネクタ検索 If (sh.Connector = msoTrue) Then Set con(i) = sh i = i + 1 End If Next この後、 If strShapeName = con(i).ConnectorFormat.BeginConnectedShape.Name then・・・ If strShapeName = con(i).ConnectorFormat.EndConnectedShape.Name Then・・・ というチェックをし、Trueなら、選択した図形にくっついているコネクタなんだな・・・というチェックをしたいのですが、ここで質問です。 (1)の段階で選択された図形の名前は、"グループ1"。 しかし、(2)のcon(i).ConnectorFormat.BeginConnectedShape.Nameでコネクタと繋がっている同じ図形の名前は、VBA上では何故か"Freeform 1"という名前を取得してしまいます。 これでは永遠に一致する事はありません。 Excelのワークシート上の左上にある名前空間(?シェイプを選択すると名前が出てくるところ・・・)には"グループ1"と表示されます。 しかし、ここに"Freeform 1"と入れても同じ図形が選択されます。 同じ図形なのに何故二つの名前を持ってしまっているのでしょうか・・・? そしてどうやったら、con(i).ConnectorFormat.BeginConnectedShape.Nameで、"グループ1"の名前を取得するのでしょうか?? どなたかご教授下さい。

  • エクセル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.を打ち込んでいたら、 「コンパイルエラー:プロシージャが大きすぎます」とエラーが出てしまいました。 ループさせればよいのだろうと試してみたのですが、元のセルの指定方法や、オートシェイプの出現させるせるの指定方法がわかりません。 どのようにすれば、データー元の範囲を指定して、それに対応したセルにオートシェイプを出現させる事が出来るようになるでしょうか。 お知恵を貸していただけないでしょうか。よろしくお願い致します。

  • エクセルのオートシェープ削除について

    セルE9:J9までに斜めの斜線を引いて、削除するマクロを 初心者なりに作成しました。 斜線作成は以下のような感じです。 Set myRng = Range("E9:J9") For Each sp In ActiveSheet.Shapes If Not Intersect(Range(sp.TopLeftCell,sp.BottomRightCell), myRng) Is Nothing Then sp.Delete End If Next Set myRng = Nothing で、フォームのボタンに登録させて罫線作ります。 ついでにリドゥボタン(戻る)も作成してやってみたのですが 以下のような感じで Set myRng = Range("E9:J9") For Each sp In ActiveSheet.Shapes If Not Intersect(Range(sp.TopLeftCell, sp.BottomRightCell), myRng) Is Nothing Then sp.Delete End If Next Set myRng = Nothing ですが、L9にリスト表示(入力規則のリストを設定)させたら If Not Intersect(Range(sp.TopLeftCell, sp.BottomRightCell), myRng) Is Nothing Then のところで1004エラーがでます。 リストはどうしても使用しなければならないので、どうしたらよいか? どなたか詳しい方おられましたら、ご指導おねがいします。

  • エクセルVBA/シェープの文字列を取得

    エクセル2010です。 BOOK内の各シートにボタンやチェックボックス、ラベルやテキストボックスなどが配置されています。 これらの貼り付けられたものの一覧を作りたいのです。 Sub obj_Check() Dim st Dim sp Dim i As Long For Each st In Sheets For Each sp In st.Shapes i = i + 1 With Sheets("Sheet3") .Cells(i, "A").Value = sp.Name ' .Cells(i, "B").Value = sp.Caption ’これがエラー .Cells(i, "C").Value = st.Name End With Next sp Next st End Sub とやってみましたがsp.Captionがエラーになります。 .Cells(i, "B").Value = sp.Shapes.Range.Character.Text としても同じです。 どうやったら、シェープに書かれた文字列が取得できるのでしょうか?

  • excel オートシェープでマクロエラー

    どうにも不思議な現象が発生して困っています。 どなたか原因と解決方法を教えてください。 ワークシートに挿入した図形にマクロを登録し、選んだ図形によって処理を変えます。 登録したマクロに row = ActiveSheet.Shapes(Application.Caller).TopLeftCell.row を書いて、図形のある行を取得し、どの図形がクリックされたかを判断しています。 不思議なのはここからで、 【その1】  ずっと何年間も不具合無く動作していたのに急に「指定した名前のアイテムがみつかりませんでした。」というエラーが発生するようになりました。  しかも1回目に図形をクリックしたときは正常に動作するのに、続けて2回目をクリックするとこのエラーが出ます。 そして、デバッグでVB画面に移り、マクロを一度停止して再起動すると、また1回目は正常動作するのに2回目はエラーとなります。 【その2】 原因をさぐるためにrow = ActiveSheet.Shapes…の行の前にブレークポイントを設定してみたところ、ブレークポイントを置いて停止後に継続させると何回でも正常に動作します。 この現象自体が不明です。 どなたかよろしくお願いいたします。

  • オートシェイプの文字が更新されない。

    こんにちは。 タイトルの件で、投稿いたします。 【現状】 ・EXCEL20007を使用しています。 ・シート構成は、カテゴリ選択シート、メニューシート、その他20シート程度。 --- 現在マクロを使用して、ある機能を実装しています。 【機能】  カテゴリシートでカテゴリを選択し、メニューシートへ遷移します。  この遷移時に、カテゴリ名をその他20シートのオートシェイプに反映させた状態で、  メニューシートを表示したいのです。 以下のマクロでそれは実現しました。 しかし、20シート中数シートで、オートシェイプのテキストが更新されていない場合がありました。 この場合、「カテゴリ名表示」のオートシェイプをクリックすることにより、 オートシェイプのテキストが更新されます。 なぜ、クリックしないと更新されないのでしょうか。 以下のマクロでのテキスト代入後、再度オートシェイプをselectするようにするなど、 そういった1文を追加してみたりしましたが、変化はありませんでした。 '================================================================== '== '各シートのオートシェイプ「カテゴリ名表示」にカテゴリ名をセット '================================================================== カテゴリ名 = カテゴリシート..Range("A1").Value  For Each sht In Worksheets    If sht.Visible = True Then      sht.Activate      For Each objShp In ActiveSheet.Shapes        'カテゴリ名表示というオートシェイプがあるかチェック        If objShp.Name = "カテゴリ名表示" Then          '存在すれば、カテゴリ名をセット          sht.Shapes("カテゴリ名表示").Select          Selection.Characters.Text = カテゴリ名        End If      Next    End If  Next '================================================================== 以上、原因をご存じの方や思い当たる節がある方、どうかご教示ください。 わかりにくい部分などがありましたら、ご指摘いただければ追記させていただきます。 よろしくお願いいたします。

  • Excel VBA シェイプの原型のサイズ取得方法

    VBAでシェイプの縦横比を%指定で変更したく、下記のように書いています ActiveSheet.Shapes("Picture 208").Select Selection.ShapeRange.LockAspectRatio = msoFalse Selection.ShapeRange.ScaleWidth 2, msoFalse '横2倍の大きさに ところが、ScaleWidthが見ている数値が元の図形のものと違うようです。原因を探すためにシェイプの原型のサイズ(幅や高さの数値)を知りたいのですが、VBAからアクセスできるプロパティやメソッドはあるでしょうか?

  • エクセル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」あるいは他の方法で指定する方法はないのでしょうか?

専門家に質問してみよう