• ベストアンサー

ShapeのVBAの中での取り扱い

ShapeのVBAの中での取り扱いに関して、サジェスチョン願います。 Shapeに文字が書き込まれていない段階で、選択して文字を読み込み判定しようとするとエラーとなります。 下記のVBAでは、5番目のShapeが該当します。 このエラーを防ぐためには、On Error Resume Nextが有効ですが、他の方法を探しています。例えば、charactor=trueみたいなもの。 ----- Sub Shapeの調査() Dim nametemp(10) As String Dim temp As Integer Dim i As Integer Dim aaa As Variant 'On Error Resume Next ActiveSheet.Shapes.AddShape(msoShapeRectangle, 50, 50, 50, 50).Select ActiveSheet.Shapes.AddShape(msoShapeOval, 100, 100, 50, 50).Select ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, 150, 150, 50, 50).Select ActiveSheet.Shapes.AddShape(msoShapeRectangle, 200, 200, 50, 50).Select ActiveSheet.Shapes.AddShape(msoShapeOval, 250, 250, 50, 50).Select temp = ActiveSheet.Shapes.Count For i = 1 To temp ActiveSheet.Shapes(i).Select nametemp(i) = ActiveSheet.Shapes(i).Name Next For i = 1 To temp / 2 + 1 '4つのshapeに対し、文字を書き込もうとする ActiveSheet.Shapes(nametemp(i)).Select Selection.Characters.Text = "" Next For i = 1 To temp / 2 '3つに対して、文字を書き込む ActiveSheet.Shapes(nametemp(i)).Select Selection.Characters.Text = "zzzzz" Next For i = 1 To temp ActiveSheet.Shapes(nametemp(i)).Select aaa = Selection.Characters.Text '<--5番目のShapeに対し If aaa = "zzzzz" Then MsgBox (aaa)'<--errorとなる。 Next End Sub

noname#95859
noname#95859

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

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

こんにちは。 >エラーは、これ以外にも起き得るというのが、On Error Resume Nextを使いたくない理由です。 おっしゃっている意味が良く分りません。 実行時エラーは、内容がどんなであれ、あくまでも、エラーとして、実行コードとしての要件には満たしません。今回は、これでよいのかもしれませんが、エラー番号で判定し処理するのは、エラー処理ルーチンを使う場合です。これは、On Error Resume Nextよりも、もう一段レベルの高い技術です。 どのように On Error Resume Next を想像しているか分りませんが、プロシージャー内の行頭で、On Error Resume Next をポンと置いて、これで安泰だっていうのは、それは、ある意味「初心者のVBAの反則技」です。 そうではなく、エラーの生じるところだけ、On Error Resume Next と On Error Goto 0 ではさんで、エラーが発生したところを回避させる方式です。これは、実際、エラー値のあるものを引数にした時など、回避する方法がありません。そういう場合に良く使う方法です。今回のように、まだ、変数 aaaが生きている場合は、"TypeName" や "VarType" で取れることはあります。(i.e. If VarType(aaa)= vbString Then ...) しかし、そうでない場合は、エラートラップ以外の方法を探すというのは、なかなか大変なことになることがあります。 でも、私は、#1で申したことは、以下のようにすればよいことを指しているのです。今、私が考えている範疇/私のレベルでは、問題がないように思います。どこかいけない部分があるのでしょうか?  With ActiveSheet   ・   ・   For i = 1 To temp      With .Shapes(i).DrawingObject       On Error Resume Next  'エラートラップ開始       aaa = .Characters.Text        If aaa = "zzzzz" Then          MsgBox i & " : " & aaa        End If       On Error GoTo 0  'エラートラップ終了      End With    Next   End With

noname#95859
質問者

お礼

ありがとうございます。 >On Error Resume Next と On Error Goto 0 ではさん >で、エラーが発生したところを回避させる方式です。 On Error Goto 0で終了させることができるのですね。知りませんでした。昔、サブルーチンに飛んだ中でエラーが発生した時に、呼び出し元で定義してあったエラー処理を実行してしまい、困った思いをしました。 これなら、ローカルな処理として扱えます。大変参考になりました。重ねて御礼を申し上げます。

その他の回答 (2)

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

こんな感じでいいと思いますが・・・ aaa = Selection.Characters.Text If TypeName(aaa) = "String" Then  If aaa = "zzzzz" Then MsgBox (aaa) End If

noname#95859
質問者

お礼

ありがとうございます。TypeNameというのがあるのですね。Help等で、そこにたどり着けるようになりたいものです。

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

こんにちは。 >このエラーを防ぐためには、On Error Resume Nextが有効ですが、他の方法を探しています。 私は、その方法が簡単でよいと思います。失礼ですが、ObjectをSelectして、そのSelection から、プロパテイを取るというのは、まだ、慣れていないような気がします。 その段階で、なぜ、エラートラップがいけないのか分りません。私なら、その場面で、On Error Resume Next を使っています。 なぜ、エラーが起こるのか、お分りになっていないのではないでしょうか?理由は、Textプロパティ自体が生成されていないので、値を取れないのですから、そういう場合は、エラートラップで良いはずです。 以下のようなコードを、私は、公開コードでは、書かないですね。また、オートシェイプの名前を配列に入れるようなこともしませんね。Shapes.Count が取れているのだから、それで、Shapes(Index)でループすれば済みます。 例えば、   With ActiveSheet  ・  ・  ・   For i = 1 To temp      With .Shapes(nametemp(i)).DrawingObject       aaa = .Characters.Text       '↓ここ       If Not IsNull(.Font.Size) Then         If aaa = "zzzzz" Then          MsgBox i & " : " & aaa         End If       End If      End With    Next    End With

noname#95859
質問者

お礼

ありがとうございます。エラーは、これ以外にも起き得るというのが、On Error Resume Nextを使いたくない理由です。エラーコードをチェックすれば良いと言われそうですが。まだ、慣れていないのが本当のところかと思います。Not IsNull(.Font.Size) これを教えていただいたのは、ありがたいです。

関連するQ&A

  • エクセルVBAの記述方法の質問です。

    エクセルです。12個のセルの文字列をオートシェープの吹き出しに順に表示させるマクロをつくりました。 Sub tenki2() Dim i As Integer Dim a As String For i = 1 To 12 a = Cells(i, 2).Value ActiveSheet.Shapes("AutoShape 4").Select Selection.Characters.Text = a Application.Wait Now + TimeValue("00:00:05") Next i End Sub これで思った通り表示されるのですが、できればオートシェープをセレクトしないようにしたいのです。 (シートを保護するため) それで ActiveSheet.Shapes("AutoShape 4").Select Selection.Characters.Text = a のところを ActiveSheet.Shapes("AutoShape 4").Characters.Text = a と変えたのですが、「オブジェクトはこのプロパティまたはメソッドをサポートしていません」という実行時エラーがでてしまいました。書き方のどこがまずかったのでしょうか?ご教示いただければ幸いです。

  • エクセルVBAの構文。 どこが間違っているのでしょうか?

    以下の2つは同じ意味だと思うのですが、test2はエラーになります。どうしてなのでしょうか? Sub test1() ActiveSheet.Shapes.AddShape(msoShapeRectangle, 300#, 100#, 140#, 80#).Select Selection.Formula = "$A$1" End Sub Sub test2() With ActiveSheet.Shapes.AddShape(msoShapeRectangle, 300#, 100#, 140#, 80#) .Formula = "$A$1" End With End Sub

  • VB6 オートシェイプ描画

    VB6 オートシェイプ描画 VB6でExcel,2000(ActiveSheet)にオートシェイプを使用したいのですが、エラーが出てしまいます。 コマンドボタンクリック時、エラー ------------------------------- 実行時エラー'1004': 指定された値は境界を超えています。 ------------------------------- AddLineは出来たのですが四角や円がこのエラーです。どこが間違えているのでしょうか? 宜しくお願いします。 Private Sub CB13_Click() Dim xlApp As Excel.Application Set xlApp = GetObject(, "Excel.Application") xlApp.ActiveSheet.Shapes.AddLine 50, 50, 100, 100 '(OK) xlApp.ActiveSheet.Shapes.AddShape(msoShapeRectangle, 50, 50, 100, 100).Select '(NG) Set xlApp = Nothing End Sub

  • VBAでオートシェイプのグループ化についての質問です。

    VBAでオートシェイプのグループ化についての質問です。 オートシェイプ線(Line)で台形を作成し全てを選択し、グループ化したいと考えています。 また、連続して台形を作成していきたいと考えています。 ?4本線を引く ?グループ化(Aグループ) ?4本線を引く ?グループ化(Aグループ)  ⇒ 連続して作成・・・ Dim st() As Variant Dim ob As Shape Dim MyLine As Shape '線の作成 Set MyLine = ActiveSheet.Shapes.AddLine(startX, startY, widthX, heightY) '線の選択 For Each ob In ActiveSheet.Shapes   ReDim Preserve st(j)   st(j) = ob.name   j = j + 1 Next ob 'グループ化 Worksheets("test").Shapes.Range(st).Select Selection.ShapeRange.Group.Select と上記コードで一つのグループは作成出来たのですが、次に作成すると Worksheets("test").Shapes.Range(st).Select Selection.ShapeRange.Group.Select でエラーになります。 恐らく前のグループ化内の線も選択してしまうのではないかと思っていますが、対処の仕方が解りません。 線の作成方法から選択方法等いろいろ意見が聞きたいと思っています。 アドバイスよろしくお願いいたします。 m(__)m

  • VBAのGroup化について

    お世話になります。以下のマクロがうまく動きません。 ------------------------------------------------- Dim objShp1 As Shape For Each objShp1 In ActiveSheet.Shapes If objShp1.Name = "Picture 3" Then ActiveSheet.Shapes.Range(Array("A", "B", "Picture 3")).Select Selection.ShapeRange.Group.Select Selection.ShapeRange.ThreeD.RotationX = -180 Selection.ShapeRange.IncrementLeft 0 Selection.ShapeRange.IncrementTop 0 Else ActiveSheet.Shapes.Range(Array("A", "B")).Select Selection.ShapeRange.Group.Select <---------(1) Selection.ShapeRange.ThreeD.RotationX = -180 Selection.ShapeRange.IncrementLeft 0 Selection.ShapeRange.IncrementTop 0 End If Next ------------------------------------------------- このマクロは全体の一部分になりますが、(1)のところでエラーになります。 どこが間違っているのか、さっぱりわかりません。 すみませんが、お助けいただければ幸いです。

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

    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でグループ化したオートシェイプにテキストを編集するコード

    Excelの四角のオートシェイプで、例えば、「四角1」「四角2」「四角3」という名前のオートシェイプが3つあったとしてテキスト編集で同じ文字列を入れたいとき、 For a = 1 To 3 ActiveSheet.Shapes("四角" & a).Select Selection.Characters.Text = "文字列" Next a とすればできるのですが、「四角1~3」をグループ化し、名前を「四角」としたとき、 ActiveSheet.Shapes("四角").Select Selection.Characters.Text = "文字列" とするとエラーが出てしまいます。グループ化されたオートシェイプのテキスト編集は、一度グループを解除し、それぞれテキスト編集しなければならないのでしょうか? 回答よろしくお願いします。

  • 選択したセルにピッタリ合うオートシェイプの挿入

    よろしくお願いいたします。 下記のコードは行方向では選択したセルとピッタリに四角のオートシェイプが挿入できるのですが、列方向では常に1行です。 横方向も選んだ範囲だけ広がるようにするにはどう変えたらよいでしょうか。 Set shrect = ActiveSheet.Shapes.AddShape(msoShapeRectangle, _ Selection.Left, Selection.Top, Selection.Offset(0, 1).Left - Selection.Left, _ Selection.Height)

  • やはり図形のクリアで実行時エラー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

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

専門家に質問してみよう