私の記事からExcelVBAを使用したCSVファイルの作成と書き込み
この記事では、CSVファイルを作成して書き込むための2つのVBAコードサンプルを提供します。
- OpenForOutputをFreeFileとして使用してCSVファイルを作成します。
- FileSystemObjectオブジェクトを使用してCSVファイルを作成します。
私は主に後者のアプローチを好みます。たとえば、サブフォルダー内のすべてのファイルを再帰的に処理するなど、さらなるコーディングにFileSystemObjectを使用しているためです(ただし、この手法はこの記事では使用されていません)。
コードノート
このコードは、通常のVBAコードモジュールから実行する必要があります。そうしないと、ユーザーがConstの使用法を指定してThisWorkbookまたはSheet Codeペインからコードを実行しようとすると、コードでエラーが発生します。
ThisWorkbookセクションとSheetコードセクションはイベントコーディング専用に予約する必要があり、「通常の」VBAは標準のコードモジュールから実行する必要があることに注意してください。
サンプルコードの目的上、CSV出力ファイルのファイルパスは、コードの上部にあるC:\ test\myfile.csvのように「ハードコード」されていることに注意してください。たとえば、関数パラメータとして、プログラムで出力ファイルを設定することをお勧めします。
先に述べたように; 例として、このコードは列と行を転置します。つまり、出力ファイルには、選択した範囲の列ごとに1つのCSV行が含まれます。通常、CSV出力は行ごとに表示され、画面に表示されるレイアウトをエコーしますが、VBAコードを使用して出力を生成すると、たとえば[名前を付けて保存...]を使用した場合よりも多くのオプションが提供されることを示したいと思いました。 CSVテキストメニューオプション。
コード
Const sFilePath = "C:\test\myfile.csv"
Const strDelim = ","
'Option 1
Sub CreateCSV_Output()
Dim ws As Worksheet
Dim rng1 As Range
Dim X
Dim lRow As Long
Dim lCol As Long
Dim strTmp As String
Dim lFnum As Long
lFnum = FreeFile
Open sFilePath For Output As lFnum
For Each ws In ActiveWorkbook.Worksheets
'test that sheet has been used
Set rng1 = ws.UsedRange
If Not rng1 Is Nothing Then
'only multi-cell ranges can be written to a 2D array
If rng1.Cells.Count > 1 Then
X = ws.UsedRange.Value2
'The code TRANSPOSES COLUMNS AND ROWS by writing strings column by column
For lCol = 1 To UBound(X, 2)
'write initial value outside the loop
strTmp = IIf(InStr(X(1, lCol), strDelim) > 0, """" & X(1, lCol) & """", X(1, lCol))
For lRow = 2 To UBound(X, 1)
'concatenate long string & (short string with short string)
strTmp = strTmp & (strDelim & IIf(InStr(X(lRow, lCol), strDelim) > 0, """" & X(lRow, lCol) & """", X(lRow, lCol)))
Next lRow
'write each line to CSV
Print #lFnum, strTmp
Next lCol
Else
Print #lFnum, IIf(InStr(ws.UsedRange.Value, strDelim) > 0, """" & ws.UsedRange.Value & """", ws.UsedRange.Value)
End If
End If
Next ws
Close lFnum
MsgBox "Done!", vbOKOnly
End Sub
'Option 2
Sub CreateCSV_FSO()
Dim objFSO
Dim objTF
Dim ws As Worksheet
Dim lRow As Long
Dim lCol As Long
Dim strTmp As String
Dim lFnum As Long
Set objFSO = CreateObject("scripting.filesystemobject")
Set objTF = objFSO.createtextfile(sFilePath, True, False)
For Each ws In ActiveWorkbook.Worksheets
'test that sheet has been used
Set rng1 = ws.UsedRange
If Not rng1 Is Nothing Then
'only multi-cell ranges can be written to a 2D array
If rng1.Cells.Count > 1 Then
X = ws.UsedRange.Value2
'The code TRANSPOSES COLUMNS AND ROWS by writing strings column by column
For lCol = 1 To UBound(X, 2)
'write initial value outside the loop
strTmp = IIf(InStr(X(1, lCol), strDelim) > 0, """" & X(1, lCol) & """", X(1, lCol))
For lRow = 2 To UBound(X, 1)
'concatenate long string & (short string with short string)
strTmp = strTmp & (strDelim & IIf(InStr(X(lRow, lCol), strDelim) > 0, """" & X(lRow, lCol) & """", X(lRow, lCol)))
Next lRow
'write each line to CSV
objTF.writeline strTmp
Next lCol
Else
objTF.writeline IIf(InStr(ws.UsedRange.Value, strDelim) > 0, """" & ws.UsedRange.Value & """", ws.UsedRange.Value)
End If
End If
Next ws
objTF.Close
Set objFSO = Nothing
MsgBox "Done!", vbOKOnly
End Sub