【Excel VBA】If Elseとは違う条件式(Select Case)について
エンジニアのIMMRです。Excel VBAの条件式には、以前に説明したExcel VBA 条件式(If Else)とこれから説明するSelect Caseの二つあります。1.従来のIf Else条件式If Elseは条件に合った時は処理Aを、条件に合わなかったら処理Bを実行します。では、下記のようなデータがあり、複数の条件があるとします。If Elseを使用して作成すると2種類の方法が浮かぶと思
Workteria(ワークテリア)では難易度の高いものから低いものまで、スキルや経験に合わせた案件を多数揃えています。会員登録は無料ですので、ぜひ会員登録してご希望の案件を探してみてください!
フリーランス/正社員のエンジニアとして活躍するには、ご自身のスキルや経験に合わせた仕事を選ぶことが大切です。ご希望の案件がみつからない場合はお気軽にお問い合わせください!ユーザ満足度の高いキャリアコンサルタントが在籍していますので、希望条件や悩み事などなんでもご相談ください。ご希望にピッタリの案件をご紹介させていただきます。
こんにちは。IMMRです。
CSVデータを読み込んでセルに記載して、処理を行いたいということはあると思います。
CSVを読み込んで、そのあとの処理は各々業務等によって変わってくると思います。
ここではCSVデータを読み込んでセルに記載するまでの方法を説明します。
CSVデータはテキストファイルとして読み込みを行います。
そのため、ブックを読み込みを行う「workbook.open」ではなく、
テキストを読み込む「Open "C:\Users\vba.txt" For Input」の形式で読み込みを行います。
Open "パス\CSVファイル名" For Input As #1
Do Until EOF(1)
Line Input #1, buf
Loop
Close #1
Open "パス\csvファイル名" For Input As #1では、CSVファイル(パス\csvファイル名)をOPENします。
Do Until EOF(1)ではOPENしたファイルを1レコードずつ読み込みます。
Line Input #1, bufでは読み込んだ1レコードをbufにセットします。
CSVファイルが
1,aa,1x1
2,bb,2y2
3,cc,3z3
だとbufにセットされるのは「1,aa,1x1」「2,bb,2y2」「3,cc,3z3」となるので
bufの値をそのままセルに記載すると、1つのセルに「1,aa,1x1」となってしまいます。
「1,aa,1x1」ではなく、「1」「aa」「1x1」のように","(カンマ)区切りで代入したい場合はもう、ひと手間が必要です。
先ほどのbufを","(カンマ)で区切るにはSplit関数を使います。
これによりカンマで区切った値より配列を作成します。
tmp = Split(buf, ",")
※tmpはVariant型で宣言しています。
※(buf, ",")の,(カンマ)は、カンマで区切るという意味です。
これにより、bufの中に「1,aa,1x1」がセットされていても「1」「aa」「1x1」と区切ることが出来ます。
区切ったものは、tmp(0)、tmp(1)、tmp(2)といった形式になりました。
ちなみに一番目の「1」はtmp(0)に、セットされています。これは配列は1からではなく、0から始まるためです。
Split関数を使って","(カンマ)を区切ることが出来き、tmp(0)、tmp(1)、tmp(2)に分けること出来ます。
しかし、区切った配列がいくつあるのか、tmp(?)まであるのかがわかりません。
データによって、変わる場合は、少なかったり、多すぎたりとなってしまいます。
そういった場合はカンマで区切った配列が最大でいくつかを確認する必要があります。
そうすれば、データごとに変わっても問題がなくなります。
確認方法は以下の通りです。
UBound(tmp)
配列tmpの再列の最大数を確認出来ます。
tmp(0)、tmp(1)、tmp(2)があるとすると最大数は2です。
※最大値が2だから2個の配列があるという意味ではありません。
配列0からカウントして、MAXが2という意味なのでtmp(0)、tmp(1)、tmp(2) の合計3個になります。
サンプルコード
Sub TEST33_1()
Dim i As Long, j As Long
Dim File_name As String
Dim tmp As Variant
With Application.FileDialog(msoFileDialogFilePicker)
.InitialFileName = "C:\logdata"
If .Show = 0 Then Exit Sub
File_name = .SelectedItems(1)
End With
j = 1
Cells(j, 1) = Dir(File_name)
j = j + 1
Open File_name For Input As #1
Do Until EOF(1)
Line Input #1, buf
tmp = Split(buf, ",")
j = j + 1
For i = 0 To UBound(tmp)
Cells(j, i + 1) = tmp(i)
Next
Loop
Close #1
End Sub
上記のサンプルコードについて簡単に説明します。
With Application.FileDialog(msoFileDialogFilePicker)
~
End With では、ダイアログボックスより処理に必要なファイルを選択しています。
詳細は他の記事にて説明しているのでご参照下さい。
【Excel VBA】ダイアログボックスより処理に必要なファイルを選択する方法
j = 1
Cells(j, 1) = Dir(File_name)では、Cells(1, 1)(jには1が代入されているため)に選択したファイル名を記載しています。
Open File_name For Input As #1でCSVファイル(ダイアログで選択した)を開きます。
Do Until EOF(1)では、CSVファイルを1レコードずづ最後まで読み込みます。
Line Input #1, bufでは、読み込んだ1レコードをbufに格納します。
tmp = Split(buf, ",")では","(カンマ)区切りで配列に格納します。
For i = 0 To UBound(tmp)のUBound(tmp)は先ほど","(カンマ)区切りで格納した配列の最大値を取得して、繰り返し処理をします。
Cells(j, i + 1) = "'" & tmp(i)は、先ほど","(カンマ)区切りで格納した配列全てを1つ1つセルに記載しています。
では、CSVデータを読み込みます。使用するCSVは下記の中にある「20210401_log」を選択します。
図1 CSVデータの配下
そして、CSVデータの中身はこのようになっています。
図2 CSVデータの中身
では、実行します。
使用するのは、上記であげたサンプルコードです。
図3 マクロの実行
CSVを読み込み、セルの一つ一つに記載することができました。
しかし、B列とC列がおかしくなっています。
CSVデータでは「202104010420」になっていたものが、「2.02E+11」となっております。
これはエクセル内で行われている自動の変換機能により変わってしまいます。
このようにならないためには、はじめからセルの書式を文字列などにしておくか
あるいはセルの入力時に文字列のフォーマットを変更しなくてはいけません。
セルのフォーマットを文字列にするには、
セル.NumberFormatLocal = "@"
とします。これにより、セルのフォーマットが文字列になるので
「202104010420」とセル内に記載されたとしても「2.02E+11」にはなりません。
下記のようにサンプルコード一部(Cells(j, i + 1) = "'" & tmp(i))の上に
Cells(j, i + 1).NumberFormatLocal = "@"を追加します。
Line Input #1, buf
tmp = Split(buf, ",")
j = j + 1
For i = 0 To UBound(tmp)
Cells(j, i + 1) = tmp(i)
Next
Loop
↓↓↓↓↓
Line Input #1, buf
tmp = Split(buf, ",")
j = j + 1
For i = 0 To UBound(tmp)
Cells(j, i + 1).NumberFormatLocal = "@"
Cells(j, i + 1) = tmp(i)
Next
Loop
上記で紹介したようにプログラムを修正して実行すれば、先ほどのように「2.02E+11」にならなくなります。
しかし、「202104010420」と長くなってしまうため下記のように列幅のズレが生じてしまうことがあります。
図4 列幅のズレ
このようにB列は全ての値が表示されていなかったり、C列は値がはみ出してしまったりして、
見た目がよくない結果になってしまいます。
その場合は、
Columns(列).AutoFitを使って、列幅を自動設定することができます。
詳細は、他の記事で紹介していますのでご参照下さい。
【Excel VBA】列の幅を自動設定するAutoFitメソッド
上記でいくつか説明していきました。その修正版のサンプルコードは以下のとおりです。
Sub TEST33_2()
Dim i As Long, j As Long
Dim File_name As String
Dim tmp As Variant
With Application.FileDialog(msoFileDialogFilePicker)
.InitialFileName = "C:\logdata"
If .Show = 0 Then Exit Sub
File_name = .SelectedItems(1)
End With
j = 1
Cells(j, 1) = Dir(File_name)
j = j + 1
Open File_name For Input As #1
Do Until EOF(1)
Line Input #1, buf
tmp = Split(buf, ",")
j = j + 1
For i = 0 To UBound(tmp)
Cells(j, i + 1).NumberFormatLocal = "@"
Cells(j, i + 1) = tmp(i)
Next
Loop
Close #1
Columns("B:C").AutoFit
End Sub
ここでは上記で説明した
セルのフォーマットを文字列にする「NumberFormatLocal = "@"」と
列の幅を自動設定する「AutoFit」を
【2.CSVを読み込むサンプルコード】で紹介したサンプルコードに追加しています。
では、再度サンプルプログラムを実行します。
図5 ブック(マクロ実行前)
手順は【3.CSVを読み込むサンプルコードの実行】と同じです。
マクロを実行するとファイルを選択するダイアログボックスが表示されます。そして、「20210401_log」を選択します。
選択すると下記のような実行結果が表示されます。
図6 ブック(マクロ実行後)
CSVデータを読み込んでセルに記載することができました。
また、セルの幅も幅ズレしないできちんと自動調整ができています。
そのような方はぜひ、Workteriaサイトをご利用ください!
定期的にご本人に合う高額案件を紹介
リモートワークなど自由な働き方ができる案件多数
専属エージェントが契約や請求をトータルサポート