【他のレンジ/シート/ブックを更新する】
1 あるレンジから別レンジを更新
2 あるシートから別シートを更新
3 逆Z式並びで更新
4 セルで指定したシートを更新
5 複数シートを連続更新
6 Subプロシージャの定義と呼び出し
7 あるブックから別ブックを更新
逆Z式並びで更新
今回は、Excel VBA/マクロによって、5列×2行の逆Z式並びとなるように
行番号と列番号を算出しながらセルの値を更新します。
特定の列数毎に改行し表並びで表示
マクロ『シートからシート4』では、『漢字入力帳』シートに用意した10問の漢字文字列を読みこみ、
『漢字学習帳』シートに漢字問題を、10列の横並びで書きこむという処理を実行しました。
次は、Excel VBA/マクロによって、『漢字入力帳』シートに用意した10問の漢字文字列を読みこみ、
『漢字学習帳』シートに漢字問題を、5列×2行の表並びで書きこむという処理を実行します。
問題番号の動きを図に表すと、次の図の水色の矢印のような動きになります。
セル(1行,10列) → セル(1行,8列) → セル(1行,6列) → セル(1行,4列) → セル(1行,2列)
→ セル(2行,10列) → セル(2行,8列) → セル(2行,6列) → セル(2行,4列) → セル(2行,2列)という
順番で、それぞれのセルに問題番号 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 を書きこみます。
『Z』を左右逆にしたような並び方なので、今後、この並び方を『逆Z式並び』と呼ぶことにします。
『逆Z式並び』で問題番号が書きこまれるセルアドレス・行・列の動きを表に表すと、
次の表のような動きになります。
マクロ『シートからシート4』をコピーして、マクロ『シートからシート5』とします。
マクロ『シートからシート4』では、『漢字入力帳』シートの最小行:『読取最小行』(2行目)から
最大行:『読取最大行』(11行目)のループの中で、漢字問題作成処理の最初に、
先頭行に問題番号を読み書きするプログラムコードを追加しました。
今回は、Excel VBA/マクロによって、その問題番号を元に、5列×2行の逆Z式並びとなるように
書込問題番号行と書込列を算出しながら『漢字学習帳』シートに問題番号及び漢字問題を
書きこむプログラムコードを追加してみましょう。
宣言部を改修します。
定数『最小列 = 20』をコメントアウト
定数『最大列』に『10』列目を代入
定数『書込列数』に『5』列目を代入
定数『書込ステップ列』に『-2』を代入
定数『書込問題番号最小行』に『1』行目を代入
定数『書込問題番号行 = 1』をコメントアウト
定数『書込ステップ行』に『15』行目を代入
定数『最小行 = 2』をコメントアウト
書込問題番号行を長整数型の変数『書込問題番号行』として定義
最小行を長整数型の変数『最小行』として定義
' Const 最小列 = 20
Const 最大列 = 10
Const 書込列数 = 5
Const 書込ステップ列 = -2
Const 書込問題番号最小行 = 1
' Const 書込問題番号行 = 1
Const 書込ステップ行 = 15
' Const 最小行 = 2
Dim 書込問題番号行 As Long
Dim 最小行 As Long
コメントアウトとは、特定の箇所をコメント化してコードを無効にすることです。
Excel VBA/マクロでは、『'』をコードの先頭につけることで、そのコードをコメントにすることができます。
コメントアウトは、一時的に除外するが、後で復活させるかもしれない内容を消さずに
そのまま残しておきたいときに便利な技術です。
処理部を改修します。
ここで、四則演算(加減乗除)などの算術計算を行うための記号『算術演算子』を紹介します。
Excel VBAで用意されている主な『算術演算子』を表にまとめると次のようになります。
足し算の『+』と引き算の『-』は、数学でつかう記号と同じでわかりやすいですが、
掛け算の『*』と割り算の『/』は、数学でつかう記号と違うので要注意です。
掛け算の『*』と割り算の『/』は、パソコンのキーボードに必ず割り当てられていて、
パソコン上の算術演算子の定番となっています。
『Mod』は割り算の余りを返すという特殊な算術演算子ですが、割り算の余りによって
列が確定するようなときに便利な算術演算子です。詳しくは後ほど紹介します。
『漢字入力帳』シートの最小行:『読取最小行』(2行目)から最大行:『読取最大行』(11行目)のループの中で、
漢字問題番号を取得し、その問題番号を元に5列×2行の表並びとなるように書込問題番号行と列番号を
算出しながら『漢字学習帳』シートに問題番号および漢字問題を書きこむプログラムコードを追加します。
問題番号が書きこまれる行と列の動きを表に表すと、次の表のような動きになります。
特に青の罫線で囲んだ問題番号と行及び列の動きに着目してください。
以下、『漢字入力帳』シートの最小行:『読取最小行』(2行目)から最大行:『読取最大行』(11行目)の
ループの中にいるとイメージしてください。
(1) 書込問題番号行の算出
問題を元に書込問題番号行を算出します。
問題と書込問題番号行の関係は次の表のようになります。
この表によると、問題番号が1から5までは行が1、問題番号が6から10までは行が16となっています。
つまり、問題番号が5(=書込列数)の倍数になる毎に、
行が15(=書込ステップ行)ずつ増加しているということです。
試しに、問題番号を5(=書込列数)で割ってみます。
この問題番号 ÷ 5(=書込列数)の整数部分を取り出します。
Excel VBAでは引数の整数部分を取得する関数として、Int関数が用意されています。
◇Int関数:引数の整数部分を取得
このInt関数をつかって問題番号÷5の整数部分を取り出したときの数値を表にします。
問題番号とInt(問題番号 / 5)を比較してみると、
問題番号1~4は同じ数値0、問題番号5~9は同じ数値1、となっています。
問題番号1~5は同じ数値として0、問題番号6~10は同じ数値として1、となれば、
改行が上手くいきます。
そこで、問題番号から1を引くことで、改行が上手くいくように調整します。
問題番号 – 1 を5(=書込列数)で割ってInt関数をつかったときの数値を表にします。
問題番号1~5は同じ数値として0、問題番号6~10は同じ数値として1、となりました。
次は、問題番号1~5は同じ行として1、問題番号6~10は同じ行として16、
となるように調整していきます。
Int((問題番号 - 1) / 5)に対して15(=書込ステップ行)を掛けたときの数値を表にします。
問題番号1~5は同じ数値として0、問題番号6~10は同じ数値として15、となりました。
このInt((問題番号 - 1) / 5)×15の数値と行を比較してみると、
行が、Int((問題番号 - 1) / 5)×15より、1多くなっています。
そこで、Int((問題番号 - 1) / 5) * 15に 1(=書込問題番号最小行)を加えることで、
行が正確な数値となるように調整します。
Int((問題番号 - 1) / 5) * 15に 1(=書込問題番号最小行)を加えたときの数値を表にします。
問題番号1~5は同じ行として1、問題番号6~10は同じ行として16、となり、
Int((問題番号 - 1) / 5)×15 + 1 と 行 が、全て一致しました。
書込問題番号行の算出をプログラムコードにすると、
書込問題番号行 = Int((問題番号 - 1) / 書込列数) * 書込ステップ行 + 書込問題番号最小行
となります。
更に、最小行の算出をプログラムコードにすると、
最小行 = 書込問題番号行 + 1
となります。
(2) 書込列の算出
問題を元に書込列を算出します。問題と書込列の関係は次の表のようになります。
この表によると、
問題番号が1のときは、列が10、
問題番号が2のときは、列が8、
問題番号が3のときは、列が6、
問題番号が4のときは、列が4、
問題番号が5のときは、列が2、
問題番号が6のときは、列が10、
問題番号が7のときは、列が8、
問題番号が8のときは、列が6、
問題番号が9のときは、列が4、
問題番号が10のときは、列が2、となっています。
つまり、問題番号を5(=書込列数)で割ったときの余りと列に関連性があるということです。
試しに、問題番号を5(=書込列数)で割ったときの余りを計算してみます。
Excel VBA/マクロには、割り算の余りを返すという算術演算子として、Mod算術演算子が用意されています。
◇Mod算術演算子:割り算の余りを返す
このMod算術演算子をつかって問題番号 ÷ 5(=書込列数)の余りを計算したときの数値を表にします。
問題番号と問題番号 Mod 5を比較してみると、
問題番号が1のときは、数値1、
問題番号が2のときは、数値2、
問題番号が3のときは、数値3、
問題番号が4のときは、数値4、
問題番号が5のときは、数値0、
問題番号が6のときは、数値1、
問題番号が7のときは、数値2、
問題番号が8のときは、数値3、
問題番号が9のときは、数値4、
問題番号が10のときは、数値0、となっています。
一方、
問題番号が1のときは、列が10、
問題番号が2のときは、列が8、
問題番号が3のときは、列が6、
問題番号が4のときは、列が4、
問題番号が5のときは、列が2、
問題番号が6のときは、列が10、
問題番号が7のときは、列が8、
問題番号が8のときは、列が6、
問題番号が9のときは、列が4、
問題番号が10のときは、列が2、となっています。
開始列は10(=最大列)であるため、列が10(=最大列)のときは数値が0となるようにしておきたいところです。
そこで、問題番号から1を引くことで、列が10(=最大列)のときは数値が0となるように調整します。
Mod算術演算子をつかって、問題番号 – 1 を5(=書込列数)で割ったときの余りを表にします。
問題番号が1のときは、数値0、
問題番号が2のときは、数値1、
問題番号が3のときは、数値2、
問題番号が4のときは、数値3、
問題番号が5のときは、数値4、
問題番号が6のときは、数値0、
問題番号が7のときは、数値1、
問題番号が8のときは、数値2、
問題番号が9のときは、数値3、
問題番号が10のときは、数値4、となり、
列が10のときは数値が0となりました。
次は、
問題番号が1のときは、列が10、
問題番号が2のときは、列が8、
問題番号が3のときは、列が6、
問題番号が4のときは、列が4、
問題番号が5のときは、列が2、
問題番号が6のときは、列が10、
問題番号が7のときは、列が8、
問題番号が8のときは、列が6、
問題番号が9のときは、列が4、
問題番号が10のときは、列が2、となるように調整していきます。
10(=最大列)から、(問題番号 - 1) Mod 5に対して-2(=書込ステップ列)を掛けたものを加算した数値
を表にします。
問題番号が1のときは、数値10となり、列が10、
問題番号が2のときは、数値8となり、列が8、
問題番号が3のときは、数値6となり、列が6、
問題番号が4のときは、数値4となり、列が4、
問題番号が5のときは、数値2となり、列が2、
問題番号が6のときは、数値10となり、列が10、
問題番号が7のときは、数値8となり、列が8、
問題番号が8のときは、数値6となり、列が6、
問題番号が9のときは、数値4となり、列が4、
問題番号が10のときは、数値2となり、列が2、となり、
10 + (問題番号 - 1) Mod 5 * (- 2) と 列 が、全て一致しました。
列番号の算出をプログラムコードにすると、
列番号 = 最大列 + ((問題番号 - 1) Mod 書込列数) * 書込ステップ列
となります。
(3) 以降のプログラムコード
以降、次のマクロ『シートからシート5』のように、
変数『書込問題番号行』、変数『列番号』、変数『行番号』、変数『枠領域』を更新しながら、
その値によりセル位置を指定し、
問題の更新、1文字書き込み、枠の設定、ふりがなの更新を実行します。
【マクロ『シートからシート5』】
Sub シートからシート5()
Const Est = "漢字入力帳"
Const Wst = "漢字学習帳"
Const 読取問題番号列 = "A"
Const 読取列 = "B"
Const 最大枠数 = 4
Const 漢字最小列 = 3
Const 漢字最大列 = 6
Const 読取最小行 = 2
' Const 最小列 = 20
Const 最大列 = 10
Const 書込列数 = 5
Const 書込ステップ列 = -2
Const 書込問題番号最小行 = 1
' Const 書込問題番号行 = 1
Const 書込ステップ行 = 15
' Const 最小行 = 2
Dim 読取最大行 As Long
Dim 読取行 As Long
Dim 行番号 As Long
Dim txt As String
Dim 最大文字数 As Integer
Dim 文字位置 As Integer
Dim 漢字列 As Integer
Dim 漢字名 As String
Dim 列英字名 As String
Dim 枠領域 As String
Dim ふりがな読取列 As Integer
Dim ふりがな列 As Integer
Dim ふりがな名 As String
Dim 列番号 As Integer
Dim 問題番号 As Long
Dim 書込問題番号行 As Long
Dim 最小行 As Long
読取最大行 = Worksheets(Est).Cells(Rows.Count, "B").End(xlUp).Row
列番号 = 最小列
' ===== 読取行のカウントアップS =====
For 読取行 = 読取最小行 To 読取最大行
問題番号 = Worksheets(Est).Cells(読取行, 読取問題番号列).Value
書込問題番号行 = Int((問題番号 - 1) / 書込列数) * 書込ステップ行 _
+ 書込問題番号最小行
最小行 = 書込問題番号行 + 1
列番号 = 最大列 + ((問題番号 - 1) Mod 書込列数) * 書込ステップ列
列英字名 = Replace(Worksheets(Wst).Cells(1, 列番号) _
.Address(False, False), "1", "")
枠領域 = 列英字名 & 書込問題番号行
Worksheets(Wst).Range(枠領域).Value = 問題番号
Worksheets(Wst).Range(枠領域).Font.Size = 10
txt = Worksheets(Est).Cells(読取行, 読取列).Value
最大文字数 = Len(txt)
' ===== 対象文字列文字位置のカウントアップS =====
For 文字位置 = 1 To 最大文字数
行番号 = 最小行 + 文字位置 - 1
Worksheets(Wst).Cells(行番号, 列番号).Value = Mid(txt, 文字位置, 1)
Next 文字位置
' ===== 対象文字列文字位置のカウントアップE =====
' ===== 漢字列のカウントアップS =====
For 漢字列 = 漢字最小列 To 漢字最大列
漢字名 = Worksheets(Est).Cells(読取行, 漢字列).Value
If 漢字名 <> "" Then
文字位置 = InStr(Worksheets(Est).Cells(読取行, 読取列).Value, _
漢字名)
If 文字位置 > 0 Then
行番号 = 最小行 + 文字位置 – 1
列英字名 = Replace(Worksheets(Wst).Cells(1, 列番号) _
.Address(False, False), "1", "")
枠領域 = 列英字名 & 行番号
Worksheets(Wst).Range(枠領域).Borders.LineStyle _
= xlContinuous
Worksheets(Wst).Range(枠領域).Value = ""
ふりがな読取列 = 漢字列 + 最大枠数
ふりがな名 = Worksheets(Est).Cells(読取行, ふりがな読取列).Value
If ふりがな名 <> "" Then
ふりがな列 = 列番号 + 1
列英字名 = Replace(Worksheets(Wst).Cells(1, ふりがな列) _
.Address(False, False), "1", "")
枠領域 = 列英字名 & 行番号
Worksheets(Wst).Range(枠領域).Value = ふりがな名
Worksheets(Wst).Range(枠領域).Font.Size = 8
Worksheets(Wst).Range(枠領域).HorizontalAlignment _
= -4131
Worksheets(Wst).Range(枠領域).Orientation = -4166
Worksheets(Wst).Range(枠領域).ShrinkToFit = True
End If
End If
End If
Next 漢字列
' ===== 漢字列のカウントアップE =====
列番号 = 列番号 + 書込ステップ列
Next 読取行
' ===== 読取行のカウントアップE =====
End Sub
それでは、マクロ『シートからシート5』を実行してみます。
『漢字入力帳』シートに用意した10問の漢字文字列が、文字分割されて『漢字学習帳』シートに、
『逆Z式並び』で書きこまれました。