• ベストアンサー

VBA、このようなケースはどうしたらよいでしょうか?

すみません。VBA初心者なので質問がちぐはぐになるかと思いますが、よろしく お願いいたします。 Sub セル番地() Worksheets("Sheet1").Select Cells(2, 2).Select Range(Selection, Selection.End(xlDown)).Select rnum = Selection.Rows.Count - 1 MsgBox rnum End sub 上のVBAでシート1に数字入力されているセルの数を判断します。 Sub sheetcopy() For X = 3 To 100 If Cells(X, 2) <> "" Then Cells(X, 2).Copy Destination:=Worksheets("Sheet1").Cells(X + rnum, 2) ElseIf Cells(X, 2) = "" Then Exit For End If Next End sub このVBAは、選択しているシートに入っている数字をシート1へコピーするものです。 ”セル番地”で判定した変数rnumを、”sheetcopy”に記載されている変数rnum へ渡すためにはどのようにしたらよいでしょうか? 引数付きプロシージャの説明を読んでみたのですが、いまいちわかりませんでした。最終的には、各シートに入力されている数値をシート1のあいているセルへどんどんコピーさせたいのです。ひとつのプロシージャに書けば、問題なく動くのですが、見た目をすっきりさせたいと思います。 イメージとしてはこんな感じです。 sub sheetcomplete () call セル番地 Worksheets("Sheet2").Select call sheetcopy call セル番地 Worksheets("Sheet3").Select call sheetcopy ~ ~ End sub そもそも、よくわかっていないので滑稽に見えると思いますが、よろしくご指導ください。

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

  • ベストアンサー
  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.5

#4の補足について。 CurrentRegionプロパティについて (1)a=Range(x).CurrentRegion.Rows.Countはデータ入力済みのセルの塊について、塊の行数を数える。塊とは上下左右スペースがあるとそこで途切れると考える。そして長方形区画を考える。したがって「データ入力済みのセルの塊」が確実な中のセルを、Xとして指定しないと、変なことになるのです。Range()は先頭左上セルだけを注目するようである。Range("b2:b100")は   Range("b2")と同じと思う。 (2)ただ不思議にa=Range("b2").CurrentRegion.Rows.CountはB1に1B2がスペースとなっていると2となる。同じくB1:B5がスペースでB6:B8に数字が入っているとa=Range("b5").CurrentRegion.Rows.Countは4となる。 (3)B3:B4がスペースでa=Range("b3").CurrentRegion.Rows.Countは1となる。 (注)「スペース」とはそのセルでDELキーを押した状態を指す。本当の未入力も含む。 他のご解答の方はあまりCurrentRegionを使われないようです。私の仕事上で支障が出たことはないが。Usedrange、End(xlDown)などの差をご研究してください。

その他の回答 (4)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.4

質問のコーディングは(1)マクロの記録臭がする、Select の多用である。(2)もうひとつセル間でValueを移すのはCopyでなく、(Sheetが異なっていても=(代入) で行える。これも操作のマクロの記録からのものでしょう。Callなんて次段階の事項を使わずとも簡単になります。 Sub test01() a=Worksheets("sheet1").Range("b2:b100").CurrentRegion.Rows.Count i = a + 1 For x = 3 To 100 If Activesheet.Cells(x, 2) = "" Then Exit For Else Worksheets("sheet1").Cells(i, 2) = ActiveSheet.Cells(x, 2) i = i + 1 End If Next x End Sub このプログラムだと、同じシート上にカーソルを置いたまま2回以上実行すると累積されるのでご注意。

yokoneco
質問者

お礼

いろいろなご指摘ありがとうございます。 上記 プログラムは、とてもすっきりしていて、みていて気持ちが良いです。 参考にさせて頂きました。

yokoneco
質問者

補足

Worksheets("sheet1").Range("b2:b100").CurrentRegion.Rows.Count CurrentRegion.Rows.Count ですが、 Range("b2:b100")の範囲に、10個入力されているセルがあると10を返してきます。 しかしB1のセルに数値が入力されていると、Range("b2:b100")で範囲指定している にもかかわらず、11と数字を返してきてしまいます。 これは、しょうがない現象なのでしょうか?

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.3

No.2、に追加。sheetcopyの修正が抜けてました。 Sub sheetcopy() を Sub sheetcopy(rnum As Long) ――にしといて下さい。

yokoneco
質問者

お礼

どうも、ありがとうございました。 私の実現させたいことが、正確に動作いたしました。 さらに、今後のアドバイスも頂きうれしゅうございました。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.2

サブルーチン「セル番地」を関数として定義し、サブルーチン「sheetcopy」に引数rnumを受け取るよう修正しては。 Function セル番地() Worksheets("Sheet1").Select Cells(2, 2).Select Range(Selection, Selection.End(xlDown)).Select rnum = Selection.Rows.Count - 1 MsgBox rnum セル番地 = rnum End Fucntion sub sheetcomplete (sht_name as string) Dim rnum as Long rnum = セル番地() Worksheets(sht_name).Select Call sheetcopy( rnum ) End sub Public Sub main() sheetcomplete "Sheet2" sheetcomplete "Shhet3" End Sub プログラミングをやりだしたら、単にExcelの本だけなく、情報科学一般の本(プログラミング概論とかアルゴリズムの本とか)も併読する事を、おすすめします。 新たな視点が得られて、問題解決に役立つ事が多いので。

yokoneco
質問者

補足

■「セル番地」を関数として定義し、は以下に該当するところでしょうか? Function セル番地() セル番地 = rnum ←ここで記載されているものは、どのような意味なのでしょうか? end function ■サブルーチン「sheetcopy」に引数rnumを受け取るよう修正しては。 Call sheetcopy( rnum ) ←これが上記のご説明部分に該当するところですか? ************************************** 関数として定義するとちゃんと動くのですが、SUB セル番地()とすると、”関数、変数を定義してください”なる表示がでました。 (自分で文献を読む前にご質問して恐縮ですが、)”関数として定義する” 意味、利用の方法など、よろしかったらご教授ください。

  • gif317
  • ベストアンサー率32% (71/216)
回答No.1

>変数rnumを、”sheetcopy”に記載されている変数rnumへ渡すためにはどのようにしたらよいでしょうか? つまりプロシージャを超えた変数を利用したいのですね?それなら、 Option Explicit Dim rnum As Integer 'これでモジュール中で共通に使える と一番上に書けばこの変数rnumはどのプロシージャ間でも使えます。困難でいいでしょうか?

yokoneco
質問者

お礼

ありがとうございました。まさに、質問のポイントに対する回答でした。

関連するQ&A

  • エクセルVBAでセル選択するコードが変

    エクセルのワークシートでVBAでセル選択するコードで理解に苦しむことがあります。 通常、Cells(2, 1)はセル番地で言えばA2セル Cells(4, 1)はセル番地で言えばA4セルです。 しかし、 With .Range("B5:B15")でくくれば  .Cells(2, 1)はセル番地で言えばB6セルだと思います。 .Cells(4, 1) はセル番地で言えばB8セルだと思います。 ところが下記のコードを動かすと、なぜかC10:C12が選択されてしまいます。 この理屈がわかりません。 Sub test02()   With Sheets("Sheet1")     With .Range("B5:B15")       .Range(.Cells(2, 1), .Cells(4, 1)).Select     End With   End With End Sub なお、 .Range(.Cells(2, 1), .Cells(4, 1)).Selectを .Range(“A2:A4”).Selectに書きかえると、希望のB6:B8が選択されます。

  • セルをコピーしてシート名を取得 【VBA】

    こんばんわ。 エクセルのVBAについて、どうしてもわからなくなったので質問させて下さい。 マクロの内容は 1.一番前のシート(名前はSheet1ではありません。)のボタン35をクリック 2.シートをコピーして3番目に置く。 3.値にする。 4.シート名をセルの"DE16"に入っている値にする。 5.ボタンを消す。 以下の内容になりましたが、名前のところでデバックがおこります。 Sub ボタン35_Click() Worksheets(1).Select Worksheets(1).Copy After:=Sheets(3) Cells.Select Selection.Copy Selection.PasteSpecial Paste:=xlPasteValues Worksheets(3).Select Worksheets(3).Name = Range("DE16").Value ActiveSheet.Shapes("Button 11").Select Selection.Delete Application.CutCopyMode = False End Sub どなたかお知恵を貸して下さい。

  • 【VBA】シートのコピー ~ 値に直す

    大変お世話になります。 VBAのコードについてご教示いただけませんでしょうか。 ■やりたいこと -------------------------------------------------------------------------------- (1) 【原紙】Sheetを、同ブック内の新規シートへコピー (2) 新規シートのシート名を、[セル:B5]の値に変更 (3) 新規シートにコピーされてきた数式を値に変更 ■作成してみたコード -------------------------------------------------------------------------------- Sub SheetCopy1() Worksheets("【原紙】Sheet").Copy Before:=Worksheets("【原紙】Sheet") ActiveSheet.Name = Range("B5").Value Cells.Select Selection.Copy Selection.PasteSpecial Paste:=xlPasteValues Application.CutCopyMode = False End Sub -------------------------------------------------------------------------------- 本日初めてVBAに触れた者が、見よう見まねで『■やりたいこと』を並べたコードのため、やはりエラーになってしまいます。 上記は、どこをどう直せばよろしいでしょうか。 もしくは、そもそも間違っておりますでしょうか。 ご教示いただきたく、何卒よろしくお願いいたします。 ◎もし可能でしたら、併せてご教示ください◎ ---------------------------------------------------------------------------- (1)の動作をさせるために、【原紙】Sheetの任意の場所に”ボタン”を設置するのですが、新規シートにもコピーされるため、そのコピー側のボタンを削除できたら…とも考えていますが、そういう動作も可能でしょうか。

  • 空白セルと0値を識別させたい。(VBA)

    すみません、誰か教えていただけますか。 シートの53、54、55行目にそれぞれ値入っています。 それを3行目にビジュアル的に表現させています。 55行目はセルの色で、53行目は数値があり同じ値が 続く部分の合計を出しています。 しかし、下記の記述ですと数値が0(変数D=0)の時に うまくいきません。空白セルと認識されてしまうと思います。 何か、良い方法があれば教えて頂けませんでしょうか。 宜しくお願いします。 Sub 表示() Dim a As Long Dim c As Long Dim D As Long Dim e As String Dim f As String c = 3 For a = 3 To 64 With Worksheets("Sheet1") If .Cells(53, a) <> .Cells(53, a + 1) Then .Range(.Cells(53, c), .Cells(53, a)).Select D = WorksheetFunction.Sum(Selection) e = D f = Selection(1).Offset(1, 0).Value G = Selection(1).Offset(2, 0).Value If D <> 0 Then Selection(1).Offset(-50, 0).Value = f + "//" + e .Range(.Cells(53, c), .Cells(53, a)).Offset(-50, 0).Select Selection.Interior.ColorIndex = G End If If Selection(1).Value = "" Then .Range(.Cells(53, c), .Cells(53, a)).Offset(-50, 0).Select Selection.ClearContents Selection.Interior.ColorIndex = xlNone End If c = a + 1 End If End With Next End Sub

  • Excel VBA 選択した範囲の1行目に色を付けたい

    VBA初心者です。 セルB4~F15に表が作成されています。 プロシージャを実行して、セルB5~F15にブルー。表1行目のセルB4とF4のみに赤の色を付けるというコードを記述したいのです。 以下のように記述しました。 Sub セルに色()    Range("B4").Select    ActiveCell.CurrentRegion.Select    Selection.Interior.ColorIndex = 8    Selection.Range(Cells(1, 1),Cells(1,5)).Interior.ColorIndex = 3 End Sub Rangeでは連続シートになるため、Unionに変更してみましたが、 Unionはオブジェクトがサポートされていない旨のエラーが出ました。 どのように記述すればよいでしょうか? どうぞよろしくお願いいたします。

  • エクセルVBA ひとつ下の行を選択したい

    オートフィルタがかかっている状態で、 ひとつ下の行のセルを選択したいです。 具体的には、エクセルシートで選択したセルの情報をフォームで編集するのですが、 そのフォームの中のスピンボタンで選択しているセルを上下に移動させたいのです。 以下のコードだと、当然ですがフィルタで抽出されたセル以外も選択されてしまいます。エクセルシート上での矢印キーやENTERキー(入力後にセルを移動する方向が下のとき)と同じ動きがしたいです。 どうかお助けください。。。 Private Sub SpinButton1_SpinUp() Cells(Selection.Row - 1, Selection.Column).Select Call UserForm_Initialize End Sub Private Sub SpinButton1_SpinDown() Cells(Selection.Row + 1, Selection.Column).Select Call UserForm_Initialize End Sub

  • エクセルVBAについて

    エクセルVBA初心者で、勉強している者です。 今、ガントチャートのようなものを作っているのですが、 下記のような記述をしたのですがうまく動きません。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sub 時間グラフ作成() If Worksheets("(1)(1)(1)(1)(1)").Range("F2").Value = "10:00" Then Worksheets("(2)(2)(2)(2)").Range("T2").Select With Selection.Interior .ColorIndex = 8 .Pattern = xlSolid End With End If End Sub ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ F2のセルを空にし、「""」で実行すると動きました。 色々調べてみたものの、煮詰まってしまいました・・・。 よろしくお願いいたします。

  • VBAで空欄にデータに表示

    エクセルVBAのIFを使って、シートaのA列に値があって、B列が空欄の場合のみ、空欄のセルにシートbの値を表示させたいです。 上手くできませんでしたので、教えてください。 Sub Do文2() Dim i As Integer i = 1 If Worksheets("a").Cells(i, 2) = "" Then Do While Worksheets("a").Cells(i, 1) <> "" Worksheets("a").Cells(i, 2) = Worksheets("b").Cells(1, 1) i = i + 1 Loop End If 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で条件式について

    EXEL(VBA)で例えば、A列のデータが入っている行までの中で数値(x)が  x<2 ならばセルに色をぬる。そして空白セルと x>2ならば色をぬらない。 という条件式は、どうしたらいいのですか? Sub InteriorColor() For j= 5 to 21 worksheets(j).activate For i = 1 to 40 '30から40行ぐらい While cells(6+i,6)<>"" If(cells(6+i,6).value<2) Then ’6列7行目から  with selection.interior .Colorindex=45 .patern=xlsorid End with Wend End if Next i Next j End sub ということを連続していない列(5列ぐらい)に対してします。 同じ命令文になる部分もあるので簡潔にしたいという希望もあります。 上部の命令では無限ループの可能性があり実行が止まりません。 どのように記述したらいいのですか? また、同じブックのシート25枚のうち5枚目から21枚目に対して処理します。 5から21までのシートの間で関係ないシートが7枚目と10枚目と15枚目にあります。それを省いての処理もあれば教えてください。

専門家に質問してみよう