みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
エクセルVBAで請求データ一覧から請求書を自動で作成するシリーズ、まだまだ続きます。
前回の記事までで、請求データ一覧から請求書ひな形にデータをコピーするという処理は、完成しました。
ただ実は、セルの範囲をコピーするだけならFor~Next文を使わずに、もっと簡単で実行時間を短くできる記述の仕方があります。
今回は、エクセルVBAでセル範囲を一気にまとめてコピーする方法についてお伝えします。
なお、この記事は以下のYouTube動画と連動していますので、合わせてご覧いただければと思います。
では、行ってみましょう!
前回のおさらいと実行時間という課題
前回までで、請求データ(wsData)というシートから、請求書ひな形(wsTemplate)の該当のセル範囲に、請求データを転記するというプログラムを作りました。
請求データのイメージはこちら。
請求書ひな形のイメージをこちらです。
それで、作成したソースコードは以下の通りです。
Sub 請求書作成()
wsTemplate.Rows("21:50").Hidden = False '隠れているかもしれない行を再表示
Dim rowsData As Long '行数カウント用の変数
rowsData = wsData.Cells(Rows.Count, 1).End(xlUp).Row '最後の行数を取得
Dim i As Long, j As Long, k As Long
k = 21
For i = 2 To rowsData
For j = 1 To 3
wsTemplate.Cells(k, j).Value = wsData.Cells(i, j).Value
Next j
k = k + 1
Next i
wsTemplate.Rows(21 + rowsData - 1 & ":50").Hidden = True 'データがない行を隠す
wsTemplate.Range("A18").Value = "ご請求金額:" & Format(wsTemplate.Range("D54").Value, "#,##0") & " 円"
End Sub
実行時間は転記の回数に依存する
さて、コードの8行目から15行目なのですが、入れ子になっているFor~Next文でデータの転記を行っています。
前回の例を見る限り、行数は6、列数は3ですから、合わせて計18回の転記が行われてるということになります。
ただ、実行時間の視点で考えてみると、セルの転記の処理時間は、セルの数ではなく転記の回数に依存するという事実があります。
なので、この18回という転記の回数を減らすことができると、実行時間という点では望ましいわけです。
Copyメソッドでセル範囲をコピーする
そこで、覚えていただきたいメソッドがCopyメソッドです。
Copyメソッドは、セル範囲をコピーするメソッドで、以下のように記述します。
これで、対象となるRangeオブジェクト、つまりセル範囲をコピー先のセル範囲にコピーをすることができます。
コピー先のセル範囲は、単一セルを指定すれば、そのセルを左上にしたセル範囲への貼り付けとなります。
請求データをまとめて転記する
今回の場合、コピー元のセル範囲のアドレスは請求データの「A2:C7」、コピー先のセル範囲の左上のセルのアドレスは「A21」になりますから、以下のようなコードを使えば良いわけです。
wsData.Range("A2:C7").Copy wsTemplate.Range("A21")
8行あったコードがたったの1行です…!
実際にこれで実行してみると、以下のように転記されます。
無事に値としては正しい値がコピーされますが、書式までコピーされてしまい、想定のフォントではなくなってしまいました。
Copyメソッドはすべて貼り付け
これは、Copyメソッドを使った場合の貼り付け形式が「すべて貼り付け」であるということによります。
つまり、値だけではなく書式も含めた全てがコピーされてしまうのです。
この問題の、最も単純な解決法の一つとしては、元のデータのフォント種類とサイズを貼り付け先のそれと揃えるという方法があります。
以下のように、「Meiryo UI」の「12ポイント」に変更してみました。
これで先程のプログラムを実行すると、以下のように想定したフォント種類とそのサイズで貼り付けをすることができます。
まとめ
以上、エクセルVBAでCopyメソッドを使ってセル範囲をまとめて一気にコピー&ペーストする方法についてお伝えしました。
ソースコードはこちらです。
Sub 請求書作成()
wsTemplate.Rows("21:50").Hidden = False '隠れているかもしれない行を再表示
Dim rowsData As Long '行数カウント用の変数
rowsData = wsData.Cells(Rows.Count, 1).End(xlUp).Row '最後の行数を取得
wsData.Range("A2:C7").Copy wsTemplate.Range("A21")
wsTemplate.Rows(21 + rowsData - 1 & ":50").Hidden = True 'データがない行を隠す
wsTemplate.Range("A18").Value = "ご請求金額:" & Format(wsTemplate.Range("D54").Value, "#,##0") & " 円"
End Sub
今回の例ほどのデータ量であれば大した差は出ませんが、データの量が多くなるとその実行時間の差は如実に出てきます。
セル範囲はまとめてペーストできるときは、まとめてするというのが定石です。
さて、次回はセル範囲に変化があったとしても、上手にほしい範囲を取得する方法がありますので、それについてお伝えしたいと思います。
どうぞお楽しみに!
連載目次:データ一覧から請求書を自動で作る
お仕事において特定のデータ一覧から必要な情報を抽出するということは頻繁にありうると思います。ここではデータ一覧から請求書を作るということを目標に、実務で使えるスキルをまっすぐに身に着けることを目的としています。- 【初心者向けエクセルVBA】データ一覧から請求書を自動で作る
- 【初心者向けエクセルVBA】ワークシートをオブジェクト名で取り扱う方法
- 【初心者向けエクセルVBA】For~Next文で簡潔にプログラムを書く
- 【初心者向けエクセルVBA】行の数をカウントする&不要な行を隠す
- 【初心者向けエクセルVBA】文字列の連結&Format関数での書式変更
- 【初心者向けエクセルVBA】セル範囲を一気にまとめてコピーする方法
- 【初心者向けエクセルVBA】ワークシートのデータのある範囲だけをピッタリ取得する方法
- 【初心者向けエクセルVBA】セル範囲の平行移動をする方法・リサイズをする方法
- 【初心者向けエクセルVBA】日付データから年・月・日を取り出す
- 【初心者向けエクセルVBA】If~Thenを使った条件分岐の超入門
- 【初心者向けエクセルVBA】For~Next文でセル範囲を一行ずつ移動させる
- 【初心者向けエクセルVBA】セル範囲のクリア~ClearContentsメソッドとClearメソッド
- 【初心者向けエクセルVBA】ワークシート・セルを選択する方法の色々について
- 【初心者向けエクセルVBA】入力ダイアログを表示するInputBoxメソッドの使い方
- 【初心者向けエクセルVBA】日付データから月末日と翌月末日を自動算出する
- 【初心者向けエクセルVBA】ワークシートをコピーする方法とそのシート名を変更する方法
- 【初心者向けエクセルVBA】オブジェクトを変数にセットして取り扱う方法
- 【初心者向けエクセルVBA】Openメソッドで新たなブックを開く方法
- 【初心者向けエクセルVBA】現在マクロを書いているブックのフォルダパスを取得する
- 【初心者向けエクセルVBA】開いたブックとそのワークシートをオブジェクト変数にセットする
- 【初心者向けエクセルVBA】ワークブックを別名で保存して閉じる方法
- 【初心者向けエクセルVBA】取引先別に請求書を作成するマクロを作る