【初月無料キャンペーン中】gooドクター

以下のコードの解説をお願いしたいです。
良く分からない状態で仕事で使っているのですが
これから振られる仕事に応用したく
理解したいのでよろしくお願いいたします。


Sub Sample1()
Dim j As Long, myRng As Range
For j = 1 To Cells(1, Columns.Count).End(xlToLeft).Column
'Columns = 列
'For j = i to cells ループ処理
If Not Cells(1, j) Like "*交流電力量*" Then
If myRng Is Nothing Then
Set myRng = Cells(1, j)
Else

Set myRng = Union(myRng, Cells(1, j))
End If
End If
Next j
If Not myRng Is Nothing Then
myRng.EntireColumn.Delete

End If
End Sub

質問者からの補足コメント

  • うーん・・・

    言葉足らずで失礼いたしました。
    交流電力量という言葉を含む列以外を削除という目的は
    分かっているのですが
    出来れば1コードずつ細かく解説していただけると
    助かります。

    私のスキル自体がまだマクロの記録程度なので
    自力での理解は困難です…
    勉強しようにも業務に間に合わないので
    恥ずかしながら質問させていただきました。

      補足日時:2021/06/01 15:44
gooドクター

A 回答 (4件)

・1行目に「交流電力量」が含まれない列を削除


・1行目にデータが全く存在しない場合は問答無用で1列目を削除

という動作をします。

◆Sub Sample1()

プログラムの動作は基本的に、「Sub ~()」の直後の行から(If文、For文などといった特殊な指示がない限り)必ず1行ずつ上から下に進行し、「End Sub」に到達すると終了します。

◆Dim j As Long, myRng As Range

この行は省略形になっています。本来の書き方だと

Dim j As Long
Dim myRng As Range

のように2行になります。

これは宣言です。「j」という名前の Long 型の変数と、「myRng」という名前の Range 型の変数を宣言します。

「j」と「myRng」というのは、このプログラムの作者が勝手に作った言葉で、VBA にもともと存在しない言葉です。だから、始めに「Long 型の変数を新規作成して、これのことを今後は j と呼びます」という「宣言」をしているわけです。「myRng」も同様です。

Dim <変数名> As <データ型など>

この構文が基本です。

<データ型など>には、扱う値が整数であれば Long、小数点以下のけたがある数であれば Double、文字列であれば String と書きます。

Long を指定して宣言された変数は、「整数を入れて保管する箱」のように機能します。Range を指定して宣言された変数はちょっと特殊で、「特定のセル範囲を指し示す矢印」のように機能します。

◆For j = 1 To Cells(1, Columns.Count).End(xlToLeft).Column

これは、いわゆる「For文」という構文です。「For ~」と書かれた行から「Next」と書かれた行までの間の処理を複数回繰り返すということを意味します。

For <変数> = <最初の数> To <最後の数>

となっています。<変数>に<最初の数>から<最後の数>までの数を1回ずつ入れ直しながら処理していきます。

For j = 1 To 10
<処理A>
Next

こう書けば、<処理A>を10回実行します。
1回目は j = 1 (j に 1 が入っている)という状態で<処理A>を実行します。
2回目は j = 2 (j に 2 が入っている)という状態で<処理A>を実行します。
3回目は…… 以下同様
これを10回目までやって、ようやくNext の下の行に処理が進行します。

Cells(1, Columns.Count).End(xlToLeft).Column
は、1行目だけに注目して、1行目の「データが存在するセル」のうち最も右にあるセルが何列目であるかという数のことです。

Cells(<行番号>, <列番号>)
で特定のセルを指定します。Columns.Count の値は16384で、これはシートのすべての列の数であり、16384列目より右にセルは存在しません。なので
Cells(1, Columns.Count)
は、1行16384列目(1行XFD列)のセルのことです。

.End(xlToLeft)
は、1行16384列目のセルを選択した状態で Ctrl + ← キーを押したときに移動する先のセルを示します。Excel は、シート内で Ctrl + 方向キー を押すと、その方向に走査して値の有無が切り替わる地点に瞬間移動する機能があります。それのイメージです。

.Column
は、1行16384列目のセルを選択した状態で Ctrl + ← キーを押したときに移動する先のセルの、「列番号」、つまり「そのセルが何列目か」を意味します。だから、シート内のデータが添付画像のようになっていたとしたら、
Cells(1, Columns.Count).End(xlToLeft).Column
は 4 です。さらに言えば、For j = 1 To 4 となり、この場合 j に入れる数を 1 から 4 まで切り替えながら処理を繰り返すことになります。

◆'Columns = 列
◆'For j = i to cells ループ処理

「'」で始まる行は「コメント」といいます。

コメントはプログラムの実行時は完全に無視されるので、動作に何の影響も与えません。

コメントは、プログラムを書いたり読んだりする人が残していったメモ(覚え書き、備忘録)みたいなものとして機能します。今は実行したくないが削除もしたくないコードもコメントにされます。

◆If Not Cells(1, j) Like "*交流電力量*" Then

ここはこのプログラムの心臓部になります。
「If文」という構文です。

もし、<条件>が成立する(真実である)としたら、「If <条件> Then」から「End If」の間の処理を実行します。

(ここでは「条件」と書きますが、厳密には「命題」です。)

<条件>が成立しなかったら(嘘であったら)、「If <条件> Then」から「End If」の間の処理を実行しません。このプログラムだと、「End If」の直後に「Next」があるので For文の「繰り返し」によってまたIf Not Cells(1, j) Like "*交流電力量*" Then に戻って来ます。

「If <条件> Then」が基本形ですが、ここでは
「If Not <条件> Then」というアレンジ形になっています。Not を付けると、<条件> が成立しなかったときに「End If」までの処理を実行する、というように基本形とは逆の動作をします。

Cells(1, j) Like "*交流電力量*"
は、『1行j列目のセルに「交流電力量」という文字列が含まれている』という条件です。For文の効果でjの数が 1 ~ 最終列番号 まで切り替わりながら繰り返しこの条件を確認することになります。

添付画像の状況なら、j = 1 のとき、1行1(A)列目のセルは空白なので「交流電力量」を含みませんから、条件が成立せず、If文に「Not」があるので「End If」までの処理を実行することになります。

j = 2 のときは、条件成立、「End If」までの処理を実行しません。

j = 3 のときは「電力量」がないので不成立、実行します。

j = 4 のときは、余計な文字が前後にくっついていても「交流電力量」を含むことに変わりないので条件成立、処理を実行しません。

◆If myRng Is Nothing Then

またIf文です。
If~Then
End If
の中にさらに
If~Then
Else
End If
が入っています。

If~Then
<処理A>
Else
<処理B>
End If
は、条件が成立すれば<処理A>のみを、成立しなければ<処理B>のみを実行するように動作します。

<変数など> Is Nothing
という条件は、その<変数など>が「何も指し示していない」ことを意味します。

先述のとおり、「myRng」は「特定のセル範囲を指し示す矢印」のように機能します。
myRng Is Nothing
は、「myRng という変数が何も指し示していない」という意味です。

Range 型の変数は宣言時にもともとどこかのセルを指し示しているわけではありません。なので初めて
If myRng Is Nothing Then
に来たときはまだ myRng をいじっていないので、myRng はまだ何も指し示していません。なので初回ではこの条件は必ず成立します。

◆Set myRng = Cells(1, j)
◆Set myRng = Union(myRng, Cells(1, j))

Set <変数名> = <セル>
この構文は、<変数名>という名前の変数にその<セル>を指し示させることができます。

Set myRng = Cells(1, j)
の実行後は、myRng は1行j列目のセルを指し示すようになります。

よって、If myRng Is Nothing Then の条件は1回成立すると2度と成立しません。
なので初回のみ
Set myRng = Cells(1, j)
を実行し、次からは
Set myRng = Union(myRng, Cells(1, j))
を実行します。

Union(<セル>、<セル>)
は、2つのセル範囲を合体させた範囲を指定できます。手作業で例えるなら、Ctrl キーを押しながら複数のセルをクリックしていき、複数のセル範囲を「同時に」選択するようなものです。

Set myRng = Union(myRng, Cells(1, j))
を実行するごとに、myRng は新たなセル「Cells(1, j)」を、これまで指し示してきたセルと同時に指し示すようになります。

◆If Not myRng Is Nothing Then 以降

myRng.EntireColumn
で「myRng が指し示しているセル」が所属する列をすべて指定し、

.Delete
で指定した対象を削除します。何も削除対象を指定せずに.Delete を実行するとエラーになります。

If Not myRng Is Nothing Then
はエラーを防ぐために必要です。
myRng が何も指し示していないときは.Delete を実行させてはいけませんから。
「コードの解説のお願い」の回答画像4
    • good
    • 0
この回答へのお礼

凄く助かりました。
日々勉強のペースを上げなければと
焦っております…
本当にありがとうございます。

お礼日時:2021/06/24 09:31

For j = 1 To Cells(1, Columns.Count).End(xlToLeft).Column


jを1から右列最終まで繰り返す
・Cells(1, Columns.Count):列番号
・End(xlToLeft).Column空で無い最終の左列
⇒つまり、1列~空では無い右最終列まで

If Not Cells(1, j) Like "*交流電力量*" Then
もし、Cells(1, j) Like "*交流電力量*"で無ければ
左*は左側文字は不問、右*右側文字は不問
⇒つまり、どこかに交流電力量が有る、notだから否定

If myRng Is Nothing Then
myRngが空で有れば

Set myRng = Cells(1, j)
myRngに Cells(1, j)自身をセット

Else
myRngが空で無ければ

Set myRng = Union(myRng, Cells(1, j))
myRngにCells(1, j)を追加する

まあ、基本から学んだ方が早いと思います。
    • good
    • 0

こんにちは



1行目(タイトル行か?)で、「交流電力量」という文字を含まない列を探して、該当列を削除するものです。
変数 myRng に該当列を記憶しておいて、最後にまとめて削除する方法をとっています。

>以下のコードの解説をお願いしたいです。
どこが(あるいは何が)わからないのでしょうか?
わからないことを明示しなければ、解説のしようがありません。

もしも「全部わからない」のであれば、まずは、基本のお勉強から始めることをお勧めします。
    • good
    • 1

'Columns = 列


'For j = i to cells ループ処理
この2行はコメントです。

エクセルシートの1行目を左から右へ検索して
交流電力量と言う文字列がセル内の何処かに有ったら、
セル範囲をmyRngに追加結合する。

最後に、myRngが空でなければ、元のシートの該当列を削除する。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

gooドクター

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング