マクロ作成後に表位置がずれた場合の対処

マクロVBAの最も不便なところは、シートでセルをずらしてもセル参照が自動で変更されない事です。
しかし、マクロVBAの記述は自動で変更されません。
B2セルをシートでずらしても、Range("B2")もCells(2, 2)も変わりません。
要所位置を名前定義しておいたりテーブル化しておくことで、相対位置だけでVBAを記述し自動で対応することはできます。
一旦完成した後に、1行目は余白行にしたいとか、A列は空いていた方が見やすいとか・・・
そうなると、マクロの修正が大変なことがあります。
列数がConstやEnumにしてあったとしても、その部分の修正は必要です。
表位置がずれた場合の対処
Dim i As Long
Dim LastRow As Long
With Worksheets("Sheet1")
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LastRow
.Cells(i, 3) = .Cells(i, 1) + .Cells(i, 2)
'・・・いろいろな処理・・・
Next
End With
まあ、このようなVBAコードがあったとして、
1行目を空けたい、ついでに、A列も空けたい。
そんな場合は、どうしますか?
Dim i As Long
Dim LastRow As Long
With Worksheets("Sheet1")
LastRow = .Cells(Rows.Count, 2).End(xlUp).Row
For i = 3 To LastRow
.Cells(i, 4) = .Cells(i, 2) + .Cells(i, 3)
'・・・いろいろな処理・・・
Next
End With
上の赤太字が、修正対象部分になりますね。
もちろん、「・・・いろいろな処理・・・」この中が大量に修正が必要になります。
Dim i As Long
Dim LastRow As Long
With Worksheets("Sheet1").Cells(2, 2)
LastRow = .Cells(Rows.Count - 1, 2).End(xlUp).Row
For i = 2 To LastRow - 1
.Cells(i, 3) = .Cells(i, 1) + .Cells(i, 2)
'・・・いろいろな処理・・・
Next
End With
「・・・いろいろな処理・・・」
本来多くの変更が必要なこの部分については手を付けなくても良くなります。
もちろん、当然コード内容によりますが、ほとんど修正は必要なくなります。
理解できますか?
With Worksheets("Sheet1")
.Cells(行,列)
この行列は、A1セルを起点とした相対位置の指定になります。
.Cells(2, 2)は、2行2列目のB2になります。
Worksheets("Sheet1").Cells(2, 2)
.Cells(行,列)
この行列は、Cells(2, 2)を起点とした相対位置の指定になります。
.
CellsはRangeオブジェクトであり、RangeオブジェクトにはCellsプロパティがあります。
このCellsプロパティの引数は、元のRangeオブジェクトの先頭(左上)セルからの相対位置指定になっています。
つまり、
Cells(2, 2).Cells(2, 2)
RAnge("B2").Cells(2, 2)
これらは、B2セルを起点、つまりB2を(1,1)としての相対位置なのでC3セルになります。
完成したVBAコードは、あまり良いVBAとは言えませんが、修正ミスによる誤動作で悩むよりはマシでしょうか。
もちろん、最初から表位置が変更になる事を考慮して、コーディングしておけば問題ないのですが、
なかなか毎回そのようにはいかない事も多いでしょう。
いざと言う時の、裏ワザとして覚えておくとよいと思います。
表位置がずれることを想定したVBA
Dim ws As Worksheet
Dim startCell As Range
Dim i As Long
Dim LastRow As Long
Set ws = Worksheets("Sheet1")
Set startCell = ws.Range("C3")
With startCell
LastRow = ws.Cells(ws.Rows.Count, .Column).End(xlUp).Row
For i = 2 To LastRow - .Row + 1
.Cells(i, 3) = .Cells(i, 1) + .Cells(i, 2)
'・・・いろいろな処理・・・
Next
End With
Dim ws As Worksheet
Dim myRange As Range
Dim i As Long
Dim LastRow As Long
Set ws = Worksheets("Sheet1")
Set myRange = ws.Range("C3").CurrentRegion
With myRange
LastRow = .Rows.Count
For i = 2 To LastRow
.Item(i, 3) = .Item(i, 1) + .Item(i, 2)
'・・・いろいろな処理・・・
Next
End With
C3セルを名前定義してあればなお良いでしょう。
参考として、2通りの書き方をしてみました。
工夫をすれば、もっといろいろな書き方ができます。
.Cells(...)
.Item(...)
CellsもItemも基のRangeオブジェクトの先頭(左上)セルからの相対位置指定になります。
Offsetを使っても良いです。
テーブルならずれても問題ありません
Sub sample()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim tbl As ListObject
Set tbl = ws.ListObjects("テーブル1")
Dim col As Long
col = tbl.ListColumns("列3").Index
Dim myRange As Range
For Each myRange In tbl.DataBodyRange.Columns(col)
myRange = "[@列1]+[@列2]"
Next
End Sub
テーブルは、表範囲全体に名前定義されている状態なので、表位置がずれてもVBAの変更は基本的に発生しません。
表位置が度々ずれたりするのであれば、テーブルにしておくことでVBAの保守性はとても良くなります。
同じテーマ「マクロVBA技術解説」の記事
マクロ作成後に表位置がずれた場合の対処
ExecuteExcel4Macroについて
「Excel 4.0 マクロ」の使い方
再帰呼出しについて(再帰プロシージャー)
フィボナッチ数列(再帰呼び出し)
文字列でのセル参照と文字列の計算式について(Evaluate,INDIRECT)
リボンを非表示、2003以前ならメニューを非表示
印刷ページ設定の余白をセンチで指定する(CentimetersToPoints)
文字列としてのプロシージャー名を起動する方法(Run,OnTime)
ドキュメントの作成者を取得(GetObject,BuiltinDocumentProperties)
画像サイズ(横x縦)の取得について
新着記事NEW ・・・新着記事一覧を見る
列全体を指定する時のRangeとColumnsの違い|ツイッター出題回答 (2023-09-24)
シートのActiveXチェックボックスの指定方法|ツイッター出題回答 (2023-09-24)
ByRef引数の型が一致しません。|ツイッター出題回答 (2023-09-22)
シートコピー後のアクティブシートは何か|ツイッター出題回答 (2023-09-19)
Excel関数の引数を省略した場合について|ツイッター出題回答 (2023-09-14)
セル個数を返すRange.CountLargeプロパティとは|VBA技術解説(2023-09-08)
記号を繰り返してグラフ作成(10単位で折り返す)|ツイッター出題回答 (2023-08-28)
シートを削除:不定数のシート名に対応|VBAサンプル集(2023-08-24)
ランクによりボイントを付ける(同順位はポイントを分割)|ツイッター出題回答 (2023-08-22)
OneDrive使用時のThisWorkbook.Pathの扱い方|VBA技術解説(2023-07-26)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.マクロとは?VBAとは?VBAでできること|VBA入門
7.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
8.並べ替え(Sort)|VBA入門
9.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
10.条件分岐(IF)|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- マクロ作成後に表位置がずれた場合の対処
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。