• ベストアンサー

VBAで別のシートに図形描画

お世話になっております。 現在VBAにおいて以下のものを作っております。 Sheet3で設定を行い、コマンドボタンを押下すると Sheet2に描画を行う ところが Range(Sheets("Sheet2").Cells(HightCnt, WidthCnt), Sheets("Sheet2").Cells(HightCnt, WidthCnt)).Select のところで 「実行時エラー'1004' Rangeメソッドは失敗しました」 となります。 (どうも同じシートSheet3に描画する分には問題ないようなのですが) コマンドボタン押下時に別シートにデータ出力等行うことはできないのでしょうか? もしできるのであれば方法をおしえていただけませんでしょうか? よろしくお願いします。

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

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

Wendy02です。 補足: >まあ、ちょっとびっくりです。^^;配列変数に入れて、それを後で吐き出すわけですね。 途中を省いてしまいましたので、意味が分かりませんよね。#5の補足とお礼をみて、それだけ出来きているなら、こんなところで躓くなんて・・・、というところなんです。^^; 私は、こういう処理の場合は、そのまま、Range型の変数に入れてしまうかもしれない、と思いましたが。 With Sheets("Sheet2")  With .Range(.Cells(12, 3), .Cells(120, 120))   .Borders.LineStyle =xlNone '罫線を全部消す  End With   ・ ・ End With 罫線をまとめて消す場合は、このようにします。 それから、オートシェイプの線ではありませんでしたね。その場合は、描画不活性化という現象は起きませんね。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

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

こんばんは。Wendy02です。 まあ、ちょっとびっくりです。^^;配列変数に入れて、それを後で吐き出すわけですね。 言われてみれば、それは、簡単なところなのですね。 以下のように修正してみてください。Rangeオブジェクトは、標準モジュールからですと、Application のメンバーになるのですが、シートモジュールだと、否応なく、そのシートの配下にされてしまうので、シートとの整合性がないと、エラーが出てしまいます。そこで、「With」ステートメントで、くくってあげないといけません。 前回書いたように、これは、なかなか、気づきにくい一つです。仮に、標準モジュールでも、同じように、「With」ステートメントで書くのが正しいです。それぞれに「.(ドット)」が入っていますから、貼り付けしないのでしたら、気をつけて書いてください。Range の前、Cellsの前に入っています。 それから、これは、Select を使っていますから、画面が激しく点滅しますから、描画の手前からで良いですから、  Application.ScreenUpdating = False ' 中身  Application.ScreenUpdating = True で、コードを包んでください。これは、オートシェイプの時は、別の意味もあります。画面が不活性になってしまっても、ScreenUpDating で活性化します。本来は、Select を使わなくても出来ますが、今は、これだけでも十分だと思います。これで、コードは通るはずです。 '------------------------------------------ 描画の部分から  '==========================================================  '描画  '==========================================================  With Sheets("Sheet2") '←ココ   .Select '←ココ   '-------------------------------------------------   'まずは消す   '-------------------------------------------------   .Range(.Cells(12, 3), .Cells(120, 120)).Select '←ココ      ~ 中略 ~ For HightCnt = 1 To 100    For WidthCnt = 1 To 100     'セルを選択する     .Range(.Cells(HightCnt + 12, WidthCnt + 2), _      .Cells(HightCnt + 12, WidthCnt + 2)).Select '←ココ            ~ 中略 ~            Next WidthCnt   Next HightCnt  End With  '←ココ End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

こんにちは。Wendy02です。 >ちなみにNo1の回答者さんがおっしゃるように関数をモジュールの方に移すとうまく動きました。 それは結果論だと思います。コマンド・ボタンだけで使用するコードをあえて、標準モジュールに移さなくてはならないようなことはありません。きちんと基本に忠実にコードが書けていれば、ローカル・モジュールで通ります。エラーの原因は、簡単にいうと、ローカル・オブジェクトのSheet3に対して、Rangeオブジェクトの論理的な矛盾があるからです。だいたい、ローカルと標準モジュールの違いがはっきりとしない、1年間ぐらいは、同じようなミスを時々起こしてしまいます。 しかし、ローカル・オブジェクトのSheet3 から、他のシートの Cells プロパティも、Range プロパティ(オブジェクトではない方)も、それ自体を直接指名しても、Select では飛びません。(他に方法はあります) .Selectでは、ローカルモジュールの範囲は、オブジェクトを一旦替えてあげないといけないので、シートの変更(Worksheets("Sheet2").Select 等)が必要になります。 元々、Sheet3の静的なデータに対して何かを加えるわけではないのなら、Sheet2 にコマンドボタンがあったほうが良いかもしれません。別に、書式設定で指定すれば、印刷に映るわけでもないし、私なら、そのように作ります。 全体的なもの、特に、HightCnt,WidthCnt は、実際は、どのような流れで、何を拾っているのか分かれば、また、よろしければ、こちらでも考えてみます。 それと、.Shapes.AddShape は、あまり繰り返さないほうがよいです。バージョンによって、線画が不活性化することがあります。

maronii_now
質問者

お礼

ありがとうございます。 単純かもしれませんが、ソースコードをSheets3に戻し、Sheets("Sheet2").SelectとしてみましたがWorksheets("Sheet2").Select でNGとなってしまいました。 ちなみにソースコードを載せてみます。 (これでは分からないかもしれませんが) Sheets3(excel Object) '************************************************************** 'ウエハー描写ボタン押下時 '************************************************************** Private Sub WeferDrawBtn_Click() Call WeferDrawBtnFunc End Sub 標準モジュール '************************************************************** 'ウエハー描写ボタン押下時 '************************************************************** Public Sub WeferDrawBtnFunc() Dim WidthSize As Integer '横のサイズ Dim HightSize As Integer '縦のサイズ Dim WidthCnt As Integer '横のカウンタ Dim HightCnt As Integer '縦のカウンタ Dim CellName As String 'セルの名前 Dim CellData(110, 110) As Integer 'セルのデータ '========================================================== '縦と横のサイズを取得 '========================================================== WidthSize = Sheets("Sheet3").Range("B3") '横のサイズ HightSize = Sheets("Sheet3").Range("B2") '縦のサイズ '========================================================== '各セルの設定を取得 '========================================================== For HightCnt = 1 To 100 For WidthCnt = 1 To 100 If HightCnt <= HightSize And WidthCnt <= WidthSize Then 'セルの情報を取得 CellData(HightCnt, WidthCnt) = Val(Sheets("Sheet3").Cells(5 + HightCnt, 1 + WidthCnt)) Else CellData(HightCnt, WidthCnt) = 0 End If Next WidthCnt Next HightCnt

maronii_now
質問者

補足

こんなことはして良いか分かりませんが、すいません続きです。 '========================================================== '描画 '========================================================== Sheets("Sheet2").Select '------------------------------------------------- 'まずは消す '------------------------------------------------- Range(Sheets("Sheet2").Cells(12, 3), Sheets("Sheet2").Cells(120, 120)).Select '右下がりの線は描かない Selection.Borders(xlDiagonalDown).LineStyle = xlNone '右上がりの線は描かない Selection.Borders(xlDiagonalUp).LineStyle = xlNone '左横の線は描かない Selection.Borders(xlEdgeLeft).LineStyle = xlNone '上側の線は描かない Selection.Borders(xlEdgeTop).LineStyle = xlNone '下側の線は描かない Selection.Borders(xlEdgeBottom).LineStyle = xlNone '右側の線は描かない Selection.Borders(xlEdgeRight).LineStyle = xlNone '選択範囲の左右端以外の境界線は描かない Selection.Borders(xlInsideVertical).LineStyle = xlNone '選択範囲の上下端以外の境界線は描かない Selection.Borders(xlInsideHorizontal).LineStyle = xlNone '------------------------------------------------- '次に書いていく '------------------------------------------------- For HightCnt = 1 To 100 For WidthCnt = 1 To 100 'セルを選択する Range(Sheets("Sheet2").Cells(HightCnt + 12, WidthCnt + 2), Sheets("Sheet2").Cells(HightCnt + 12, WidthCnt + 2)).Select '使用する部分は描く If HightCnt <= HightSize And WidthCnt <= WidthSize _ And CellData(HightCnt, WidthCnt) = 1 Then '右下がりの線は描かない Selection.Borders(xlDiagonalDown).LineStyle = xlNone '右上がりの線は描かない Selection.Borders(xlDiagonalUp).LineStyle = xlNone '左横の線を描く With Selection.Borders(xlEdgeLeft) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With '上側の線を描く With Selection.Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With '下側の線を書く With Selection.Borders(xlEdgeBottom) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With '右側の線を書く With Selection.Borders(xlEdgeRight) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With End If Next WidthCnt Next HightCnt

全文を見る
すると、全ての回答が全文表示されます。
  • myCat
  • ベストアンサー率60% (9/15)
回答No.4

endy02さん、こんばんは。 ちょっと気になるところがありましたので便乗質問させて下さい。 >>Sheet3で設定を行い、コマンドボタンを押下すると >>Sheet2に描画を行う >>ところが >>Range(Sheets("Sheet2").Cells(HightCnt, WidthCnt), Sheets("Sheet2").Cells(HightCnt, WidthCnt)).Select >>のところで「実行時エラー'1004' Rangeメソッドは失敗しました」 描画のところは何も書いてないので置いておいて、上記エラーについて >エラー自体は、Range オブジェクトをSheet オブジェクトでカバーしてあげればよいだけなのですが と回答されてますが、 この●Sheetオブジェクトでカバー●とはどういうことなのでしょうか 例えば、次のようにRangeオブジェクトの前にSheetオブジェクトを付加すれば Sheet2をSelectしなくてもエラーを回避できるということでしょうか。 Sheet3のCommandButton Clickイベント ----------------------------------------------------- Private Sub CommandButton1_Click()   With Sheets("Sheet2")   .Range(.Cells(1, 1), .Cells(2, 3)).Select   End With End Sub -----------------------------------------------------   後学の為に是非ご教授ください。 意味を取り違えていましたら「VBA齧り始め」の戯言とご容赦ください。 何れにしろ、Wendy02さんのVBAの回答はとても勉強になります。 いつも感謝しながら眺めております。 ここからは質問者へ。 因みに当方の回答は標準モジュールでしか動かないコードです。 Sheet3に置く場合はシート名を付け加えないといけないのですが それは試してみてエラーが出たら再度質問するでしょうから、 その時点でそこは回答した方がより理解が深まるかなと思い書きませんでした。    

maronii_now
質問者

お礼

ご返答ありがとうございます。 Selectオブジェクトでセルを選択してもうまくできませんでしたが withでうまくできるかは試してみます。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 Sheet3 のコマンドボタンですから、Sheet3 に書いてかまわないですが、コードの全部をみないと分からないものがありますね。書き方にもよりますが、特別、Select も必要だも思いません。 エラー自体は、Range オブジェクトをSheet オブジェクトでカバーしてあげればよいだけなのですが、コードを見る限りは、Rangeオブジェクトで範囲を設定しているようにないのです。 コードの変数からの単なる想像ですから、意味が違うかもしれませんが、セルに対して範囲を設定するなら、以下のような感じにならないでしょうか?また、どちらかというと、このようなサイレントモードは、最後に、.Select を入れ目視するか、メッセージか、Beep を入れて音で確認しないと、別のシートに、いくつ同じものを作っているきか気が付きません。 '------------------------------------------------------ Private Sub CommandButton1_Click()  Dim HightCnt As Long '高さ  Dim WidthCnt As Integer '幅  Dim sLocation As String '位置  Dim r As Range '--------------------------------- '本来は、シートからの呼び出し?  sLocation = "A1"  HightCnt = 10  WidthCnt = 3 '---------------------------------  With Worksheets("Sheet2")   Set r = .Range(sLocation).Resize(HightCnt, WidthCnt)   .Shapes.AddShape(msoShapeRectangle, r.Left, r.Top, r.Width, r.Height).Select   Set r = Nothing  End With  Beep End Sub '------------------------------------------------------

maronii_now
質問者

お礼

ご返答ありがとうございます。 私がやりたかったことは Sheets3のB6~BS60に1が立っているものは Sheets2の該当する部分のセルに罫線を引くというものです。 (シリコンウエハーの形状・測定結果を描くマクロを組んでいるため) 本当はRange("B6").Selectといったようにやりたかったのですが ループでまわしながら描くのにどうして良いか分からず Range(Sheets("Sheet2").Cells(HightCnt, WidthCnt), Sheets("Sheet2").Cells(HightCnt, WidthCnt)).Selectとしたのです。 Range変数なんてあるのですね。 試してみます。 ちなみにNo1の回答者さんがおっしゃるように関数をモジュールの方に移すとうまく動きました。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • myCat
  • ベストアンサー率60% (9/15)
回答No.2

こんにちは。 原因は、Sheet2がアクティブでないのに、Sheet2のセルをSelectしているからです。 次のように先ず、Sheet2をアクティブにしてから、セルのSelectです。 Sheets("Sheet2").Select Range(Cells(HightCnt, WidthCnt), Cells(HightCnt, WidthCnt)).Select Sheet2をアクティブにしてあるのにエラーが出る場合は、変数HightCnt,WidthCntの値が不適切な値です。   以上です。  

maronii_now
質問者

お礼

ありがとうございます! モジュールの方にコードを移動してみたら実行できました。 ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。
  • ASIMOV
  • ベストアンサー率41% (982/2351)
回答No.1

コードを Sheet3 に記述していませんか? 他のシートに関わるコードは標準モジュールに記述しないと動きません

maronii_now
質問者

お礼

早速のご回答ありがとうございます。 Sheet3にコードを書いていました。 コードを標準モジュールに書いてみます。 ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VBAで実行時エラー1004が出ます

    VBAで実行時エラー1004が出ます。 「Rangeメソッドは失敗しました。Worksheetオブジェクト」です。 あらゆる可能性を調べたのですが、分かりません。誰か教えて頂けますでしょうか? 下記コードの「Cells(m, 7) =・・・」の部分がエラーになりました。 Sub ボタン1_Click() Dim 現シート As Worksheet ~ 現シート.Activate Cells(m, 7) = WorksheetFunction.VLookup(現シート.Range(現シート.Cells(m, 4)).Select, 現シート.Range(現シート.Cells(4, 104), 現シート.Cells(15, 107)).Select, 4, False) ~ End Sub 何卒宜しくお願いいたします。

  • VBAにて別シートに貼り付けたいのでができません

    今開いているファイル(A)内のシート(依頼)にVBAを以下の用に記述しました。 これをデスクトップにあるファイル(提出)内のシート(データ更新)に貼り付けたいのですが できません。 「インデックスが有効範囲にありません。」と表示されます。 どこが悪いか教えて下さい。 sub 取り込み( ) Sheets("依頼").Range(Cells(15, 2), Cells(30, 21)).Copy Workbooks.Open Filename:="C:\Documents and Settings\Administrator\デスクトップ \作業中\提出.xls" Sheets("データ更新").Select Range(Cells(15, 2), Cells(15,2)).Select     ActiveSheet.Paste Application.CutCopyMode = False End sub

  • エクセル2000VBA コマンドボタンがうまく動きません

    こんにちは、VBA初心者です。 2枚のシートがあり、「入力」というシートの任意のセルを、「出力」という別シートにコピーするという作業をコマンドボタンによって行いたいと思っています。 自分で作ってみたものは、このようになります。 Private Sub 任意の行のコピー・印刷_Click() Application.ScreenUpdating = False 'セル内容コピー Selection.Copy Sheets("出力").Select Range("A9").Select Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Sheets("入力").Select ActiveCell.Offset(0, 1).Select Application.CutCopyMode = False Selection.Copy Sheets("出力").Select Range("C9").Select (以下略) ところが、これだと 「実行時エラー1004 RangeクラスのSelectメソッドが失敗しました」と表示され、デバッグをかけると6行目のRange("A9").Selectが黄色く反転した状態になります。 どうしてでしょうか。 同じ内容のものをマクロで登録し、実行すると、何の問題もなく動くのですが… ほとほと困っております。 どうかよろしくお願いします。

  • ExcelVBA:ワークシートに付けたコマンドボタンから、セル全体をコピーするコード

    ExcelVBAでワークシートに付けたコマンドボタンを押すと、ワークシートを指定し、コピーするプログラムを作りたいのですが、「実行時エラー'1004':RangeクラスのSelectメソッドが失敗しました。」というようなエラーが出て動きません。 プログラムは以下の通りです。 Private Sub CommandButton1_Click() Sheets("Sheet1").Select Cells.Select Selection.Copy End Sub どのようにすればよいでしょうか? 回答よろしくお願いします。

  • 別シートに罫線がひけない

    表題どおりなのですが、別シートに罫線がかけません。 例えばSheet1にあるボタンをクリックするとSheet2に罫線をかく。 (コードは下記参照)としたときにエラーが発生します。 「1004 Rangeメソッドは失敗しました。」 そのため「ActiveSheet.」をはずしてみると”Sheet1”に描画されてしまいます。 なにか宣言が必要なのでしょうか? Private Sub CommandButton1_Click() Worksheets("sheet2").Activate '.Selectでも同じ For i = 4 To Range("G30").Column ActiveSheet.Range(Cells(4, i), Cells(30, i)).Borders(xlLeft).Weight = xlThin ActiveSheet.Range(Cells(4, i), Cells(30,i)).Borders(xlLeft).LineStyle = xlContinuous Next End Sub

  • アクティブでないシートのセルを選択

    Excel VBAでアクティブでないシートのセルをSelectすることはできないのでしょうか。 Selectメソッドというのは,もともとそういうものなのでしょうか。 エラー: 「RangeクラスのSelectメソッドが失敗しました。」 コード Sub aaa() With Worksheets("Sheet2") .Range(.Cells(44, 1), .Cells(48, 21)).Select End With End Sub

  • VBA シートセレクト方法

    お願いします。 エクセルVBAにて請求書確認というシートの数字を基準として 請求書入力という違うシートで同じ数字があった場合 請求書入力の特定なセルを青色で塗りつぶしたいのですが 下記のように書くとデバックしてしまいます。 '請求入力NO.チェック処理 For i = 4 To 2000 For N = 4 To 2000 If Sheets("請求入力").Cells(N, 1) = Cells(i, 6) Then Sheets("請求入力").Cells(N, 5).Select ' Range("A16").Select With Selection.Interior .ColorIndex = 8 .Pattern = xlSolid End With End If Next N Next i 説明 Sheets("請求入力").Cells(N, 5).Selectというところで 実行時エラー'1004': RangeクラスのSelectメソットが失敗しました 以上のようにエラーになります。 請求書確認とゆう同じシートで Range("A16").Selectと設定するとA16が青く 塗りつぶされます。 どのように修正すれば宜しいのでしょうか?

  • エクセルVBAでボタンを作ったシートとVBAを実行するシートを変えたい

    シート1にボタンを作成し、 そのボタンを押すと実行するVBAを作成しました。 そこで、VBAを実行するシートの指定はできるのでしょうか。 例えば、ボタンを押すと、 10行から20行まではシート2で実行させ、 30行から40行まではシート3で実行させたいと考えています。 可能でしょうか。 どうぞ宜しくお願いします。 *********************************************** 作成したVBA。ボタンはシート1にあります。 *********************************************** Private Sub CommandButton1_Click() *********************************************** ここからはシート2で実行させたい *********************************************** Range("E2").Select ActiveCell.FormulaR1C1 = "10" Range("E2").Select Selection.AutoFill Destination:=Range("E2:E101"), Type:=xlFillDefault Range("E2:E101").Select *********************************************** ここからはシート3で実行させたい *********************************************** Range("A2").Select ActiveCell.FormulaR1C1 = "100" Range("A2").Select Selection.AutoFill Destination:=Range("E2:E101"), Type:=xlFillDefault Range("A2:A101").Select End Sub

  • エクセルVBAで選択していないシートのセルコピー

    エクセルVBAで質問させてください。 現在選択していないシートから、セルの書式ごとコピーして貼り付けたいのです。 たとえば Sheets(1).Range(Cells(1, 1), Cells(4, 1)).Copy Sheets(2).Range("A1") 等とすると、Sheets(2)が選択されている状態だとエラーになってしまいます。 おそらく、Copyメソッドというのは、選択されているシートにのみ有効だからなのではないか、と思いますが、セルの値だけでなくフォントその他の書式を、別のシート(現在アクティブでない)から持ってくる方法はありますか?

  • VBA Selectの省略

    こんばんは、VBAのSelectメソッドの省略について質問させてください。 VBAにおいてSelectを使用すると処理が遅くなると聞いたことがあるので、なるべくSelectを避けるべく以下のVBAを記述しました。 内容は、シート「りんご」のA列~AN列に入っているデータを見出し項目を含めてコピー、そしてSheet1にペーストするというものです。(行数は毎回変化します。) ところが、以下を実行したところ、コピー&ペーストされたのは1行目の見出し項目のみでした。一方、「Range("A1:AN" ~」の前に「Sheets("りんご").Select」を入れたところ、全てのデータをコピー&ペーストすることができました。 この場合は、Selectを使用せずデータをコピー&ペーストすることは不可能なのでしょうか…?!どなたかご回答いただけると嬉しいです、よろしくお願いいたします。  '対象データのコピー&ペースト Sheets("りんご").Range("A1:AN" & Cells(1).CurrentRegion.Rows.Count).Copy Sheets("Sheet1").Paste

専門家に質問してみよう