[2020/05/14] 指定フォルダ内の全ファイルをクリア(サブフォルダ内もクリア) (No.174)
[2020/05/14] 指定フォルダ内の全ファイルを削除(サブフォルダ内も削除) (No.173)
[2019/09/04] バイト配列を介したバイナリファイルの読込・書込処理について (No.122)
[2019/08/26] EXEの実行ファイル(フォルダ)を取得する (No.116)
[2019/07/02] Excel ファイルの操作について(Microsoft.Office.Interop.Excel COM参照) (No.108)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
以前紹介しましたフォルダの中のファイルを全てクリアする関数を、指定フォルダのサブフォルダ内のファイルも全てクリアする様にします。
⇒指定フォルダ内の全ファイルをクリア :[Directory.GetFiles,File.Delete]指定フォルダ内の全ファイルクリア関数(サブフォルダ内もクリア)
''' ----------------------------------------------------------------------- '''
''' 指定フォルダ内の全ファイルをクリア(サブフォルダ内のファイルもクリア) ''' '''指定フォルダ '''True:正常, False:エラー ''' ----------------------------------------------------------------------- Function ClearFolderFile(ByVal astrDesFolderName As String) As Boolean '戻り値初期化 ClearFolderFile = False Try '指定フォルダ内の全ファイルを取得 Dim arrFiles() As String = System.IO.Directory.GetFiles(astrDesFolderName) '全ファイルクリア For Each strFile As String In arrFiles 'File.Create メソッドを使用してファイルを作成する Using fs As System.IO.FileStream = System.IO.File.Create(strFile) 'ファイルクローズ fs.Close() End Using Next 'サブフォルダにあるファイルをクリア(再帰呼出) Dim ArrDirs As String() = System.IO.Directory.GetDirectories(astrDesFolderName) Dim strDir As String For Each strDir In ArrDirs '自分自身を再帰呼出 If ClearFolderFile(strDir) = False Then '再帰呼出での内部のファイルのクリアがエラーの場合 Return False End If Next '正常終了 Return True Catch ex As Exception 'エラー処理が必要な場合は、ここに記述する End Try End Function
関連する記事
⇒フォルダコピー(サブフォルダ以下も含む):[Directory.GetFiles,Directory.GetDirectories]
⇒指定フォルダ内の全ファイルを削除 :[Directory.GetFiles,File.Delete]
⇒指定フォルダ内の全ファイルを削除(サブフォルダ内も削除)
⇒テキストファイル追記処理 :[File.ReadAllText,File.AppendAllText]
⇒テキストファイル先頭行削除処理 :[IO.StreamReader,IO.StreamWriter,Encoding.GetEncoding]
⇒ファイルサイズ取得 :[IO.FileInfo]
⇒テキストファイルレコード件数取得 :[IO.StreamReader]
⇒ファイル上書きコピー :[IO.FileInfo,File.Copy]
PR -
以前紹介しましたフォルダの中のファイルを全て削除する関数を、指定フォルダのサブフォルダ内のファイルも全て削除する様にします。
⇒指定フォルダ内の全ファイルを削除 :[Directory.GetFiles,File.Delete]指定フォルダ内の全ファイル削除関数(サブフォルダ内も削除)
''' ----------------------------------------------------------------------- '''
''' 指定フォルダ内の全ファイルを削除(サブフォルダも削除) ''' '''指定フォルダ '''True:正常, False:エラー ''' ----------------------------------------------------------------------- Function DeleteFolder(ByVal astrDesFolderName As String) As Boolean '戻り値初期化 DeleteFolder = False Try '指定フォルダ内の全ファイルを取得 Dim arrFiles() As String = System.IO.Directory.GetFiles(astrDesFolderName) '全ファイル削除 For Each strFile As String In arrFiles System.IO.File.Delete(strFile) Next 'サブフォルダにあるファイルを削除(再帰呼出) Dim ArrDirs As String() = System.IO.Directory.GetDirectories(astrDesFolderName) Dim strDir As String For Each strDir In ArrDirs '自分自身を再帰呼出 If DeleteFolder(strDir) = False Then '再帰呼出での内部のファイルの削除がエラーの場合 Return False End If Next '正常終了 Return True Catch ex As Exception 'エラー処理が必要な場合は、ここに記述する End Try End Function
関連する記事
⇒フォルダコピー(サブフォルダ以下も含む):[Directory.GetFiles,Directory.GetDirectories]
⇒指定フォルダ内の全ファイルを削除 :[Directory.GetFiles,File.Delete]
⇒テキストファイル追記処理 :[File.ReadAllText,File.AppendAllText]
⇒テキストファイル先頭行削除処理 :[IO.StreamReader,IO.StreamWriter,Encoding.GetEncoding]
⇒ファイルサイズ取得 :[IO.FileInfo]
⇒テキストファイルレコード件数取得 :[IO.StreamReader]
⇒ファイル上書きコピー :[IO.FileInfo,File.Copy]
-
バイナリファイルからのバイト配列への読込処理と、バイト配列からバイナリファイルへの書込処理について記します。 通常テキストファイルはバイナリファイルとは異なるものとして扱いますが、 ファイルの中身は文字コードのみで構成されたバイナリファイルとして取り扱いができます。 (データファイルは全てバイナリファイルであるとも言えますが)
■バイト配列からバイナリファイルへの書込処理
それではファイルを読込むためにファイルが存在しないと始まらないので、 バイナリファイルをバイト配列から書込む処理を説明します。
バイト配列は適当にデータを生成するとして、書込処理には System.IO.FileStream クラスの Write メソッドを使用します。Private Sub btnWrite_Click(sender As Object, e As EventArgs) Handles btnWrite.Click '書込むバイト型配列:Shift-JISの文字 "I" "J" "K" "L" "0" "1" "2" Dim arrByte As Byte() = New Byte() {&H49, &H4A, &H4B, &H4C, &H30, &H31, &H32} 'ファイルを作成して書込む (存在する場合は上書き) Dim fs As New System.IO.FileStream("sample.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write) 'バイト型配列の内容をすべて書き込む fs.Write(arrByte, 0, arrByte.Length) '閉じる fs.Close() End Sub
■バイナリファイルからバイト配列への読込処理
バイナリファイルからの読込処理では最初に System.IO.FileStream クラスを生成することで対象ファイルをオープンします。 System.IO.FileStream クラスの長さのプロパティ Length 分のバイト配列を宣言し Read メソッドで読込を行います。
Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click 'ファイルを開く Dim fs As New System.IO.FileStream("sample.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read) 'ファイルを読み込むバイト型配列を作成 Dim arrByte(fs.Length - 1) As Byte 'ファイルの内容を全て読込 fs.Read(arrByte, 0, arrByte.Length) 'ファイルを閉じる fs.Close() 'バイト配列を16進数表記の文字列で表示(各要素を「-」で連結) Console.WriteLine(BitConverter.ToString(arrByte)) End Sub
実行結果がコンソールには以下様に表示されます。確かに書込み処理されたデータが読み込まれています。
49-4A-4B-4C-30-31-32
■大きなバイナリファイルの分割読込処理
上記の読込処理では System.IO.FileStream クラスでオープンした後でファイルの大きさでバイト配列を宣言しましたが、 ファイルサイズが非常に大きい場合、メモリ確保に負担が掛かります。 そのため以下の様に、固定のバイト数での読込を複数回処理することで全ての読込処理が行えます。
Read メソッドは順次読込を行いますが、ファイルの最後まで読込、更にこのメソッドを呼び出すと結果として「0」が返ります。 よって、「0」が返った時点で処理を終了します。Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click 'ファイルを開く Dim fs As New System.IO.FileStream("sample.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read) 'ファイルを16バイトずつ読み込むバイト型配列を作成 Dim arrByte(16 - 1) As Byte While True 'ファイルの内容を全て読込 Dim nRead As Integer = fs.Read(arrByte, 0, arrByte.Length) If nRead = 0 Then Exit While End If '部分読込データ処理 'バイト配列を16進数表記の文字列で表示(各要素を「-」で連結) Console.WriteLine(BitConverter.ToString(arrByte)) End While 'ファイルを閉じる fs.Close() End Sub
実行結果がコンソールには以下様に表示されます。 書込まれているデータが7バイトのため、16バイト以下の読込となり1回で処理が終わることになります。
49-4A-4B-4C-30-31-32-00-00-00-00-00-00-00-00-00
■バイナリファイルのコピー処理
上記の分割読込処理を元にバイナリファイルコピーの処理を関数としてまとめてみました。
'''
''' バイナリファイルコピー ''' ''' <param name="SrcPath">コピー元のフルパスファイル名</param> ''' <param name="DesPath">コピー先のフルパスファイル名</param> ''' <param name="nSize">コピー分割処理バイト数</param> '''True:正常終了, False:NG '''エラーは詳細に処理していません Public Function CopyBinaryFile(ByVal SrcPath As String, ByVal DesPath As String, ByVal nSize As Integer) As Boolean CopyBinaryFile = True '読み書きの FileStream 宣言 Dim fsRead As System.IO.FileStream = Nothing Dim fsWrite As System.IO.FileStream = Nothing Try '読込ファイルを開く fsRead = New System.IO.FileStream(SrcPath, System.IO.FileMode.Open, System.IO.FileAccess.Read) '書込ファイルを開く fsWrite = New System.IO.FileStream(DesPath, System.IO.FileMode.Create, System.IO.FileAccess.Write) 'バイト配列宣言 Dim arrByte = New Byte(nSize - 1) {} 'コピー処理ループ While True '元のファイル読込 Dim nRead As Integer = fsRead.Read(arrByte, 0, nSize) If nRead = 0 Then Exit While End If 'コピー先に書込 fsWrite.Write(arrByte, 0, nRead) End While Catch ex As Exception 'エラー処理 Return False Finally 'ファイルクローズ If Not fsRead Is Nothing Then fsRead.Close() End If If Not fsWrite Is Nothing Then fsWrite.Close() End If End Try End Function 'バイナリファイルコピーのテスト用ボタンクリック処理 Private Sub btnCopy_Click(sender As Object, e As EventArgs) Handles btnCopy.Click Dim blnRet As Boolean = CopyBinaryFile("sample.txt", "sample2.txt", 4) Console.WriteLine("CopyBinaryFile...{0}", blnRet) End Sub関連する記事
⇒配列の使い方について(Dim, Redim)
⇒配列の使い方の注意点について(コピー, Clone)
-
EXEファイルの実行フォルダが必要になることはよくあります。 フォルダを取得して、そこからの相対フォルダ参照で、データフォルダなどを作成・参照を行ったりしますので、 その方法について示します。
まず最初は通常のWindowsフォームを持っているEXEファイルに付いてです。WindowsフォームでのEXEファイル取得
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim strPath As String = "" 'System.Windows.Forms.Application のSharedプロパティ「ExecutablePath」を参照 ' アプリケーションを開始した実行可能ファイルのパスを、ファイル名を含めて取得します。 strPath = System.Windows.Forms.Application.ExecutablePath Console.WriteLine("ExecutablePathdでのExeフルパス:[{0}]", strPath) '因みに、System.Windows.Forms.Application のSharedプロパティ「StartupPath」を参照 ' アプリケーションを開始した実行可能ファイルのファイル名を含まないパス取得します。 strPath = System.Windows.Forms.Application.StartupPath Console.WriteLine("StartupPathでのExeフルパス:[{0}]", strPath) End Sub
実行結果は以下の様になります。
ExecutablePathdでのExeフルパス:[C:¥TestSrv¥BlogTest¥BlogTest¥bin¥Debug¥BlogTest.EXE] StartupPathでのExeフルパス:[C:¥TestSrv¥BlogTest¥BlogTest¥bin¥Debug]
コンソールアプリの場合にはこれは使えないので、以下の様に自分自身のアセンブリを取得し、そのLocationプロパティ を取得することでEXEのフルパスが取得できます。
GetExecutingAssembly().Location でのEXEファイル取得
Module MdlMainPath 'Main関数 Sub Main() Dim strPath As String = "" 'GetExecutingAssembly().Locationでの実行ファイルのパスを取得する strPath = System.Reflection.Assembly.GetExecutingAssembly().Location Console.WriteLine("GetExecutingAssembly().LocationでのExeフルパス:[{0}]", strPath) 'パスから実行フォルダのみを取り出す strPath = System.IO.Path.GetDirectoryName(strPath) Console.WriteLine("GetExecutingAssembly().LocationでのExeフォルダ:[{0}]", strPath) End Sub End Module
実行結果は以下の様になります。
GetExecutingAssembly().LocationでのExeフルパス:[C:¥TestSrv¥BlogTest¥BlogTest¥bin¥Debug¥BlogTest.exe] GetExecutingAssembly().LocationでのExeフォルダ:[C:¥TestSrv¥BlogTest¥BlogTest¥bin¥Debug]
関連する記事
⇒フォルダコピー(サブフォルダ以下も含む):[Directory.GetFiles,Directory.GetDirectories]
⇒指定フォルダ内の全ファイルを削除 :[Directory.GetFiles,File.Delete]
⇒指定フォルダ内の全ファイルをクリア :[Directory.GetFiles,File.Delete]
-
Excel ファイルを VB.NET から操作することはいろんなシステムで要求されます。 例えば、検索されたデータ一覧を Excel ファイルに出力することや、 印刷用のテンプレート Excel ファイルを読込んで、そこにデータを設定し、出力する等です。
それで、今回は Microsoft.Office.Interop.Excel COM参照による方法について示します。 Microsoft.Office.Interop.Excel を利用するには対象となるパソコンに Excel がインストールされている必要があります。
先ずはプロジェクトに Microsoft.Office.Interop.Excel の参照設定を行う必要があります。
以下は、メニューの中の「プロジェクト(P)」⇒「参照の追加(R)...」を開いて Microsoft Excel 15.0 Object Library を選択したところです。 15.0 の部分は Excel のバージョンにより変わります。参照設定が終わると、左図の様にソリューションエクスプローラの中の「参照設定」に Microsoft.Office.Interop.Excel が現れます。
これで、プログラムの中でエクセルを利用する準備が終わりました。
早速簡単なエクセルファイルを上書きする例を示します。
今回の例はフォームにボタンを1個設置しそのクリックイベントで処理を行います。
ファイル名を「test.xlsx」とし、そのファイルの中のシートの先頭セルに "TEST123" の文字列を設定し、登録します。 (「test.xlsx」は前もって作成しておきます。)
エクセルを使う手順は以下の様に行います。- Excel オブジェクトを生成しアプリケーション起動
- Excel の Workbook のコレクションである Workbooks の取得
- Workbooks オブジェクトにより既存の Excel ファイルを Workbook に開く
- Excel の Worksheet のコレクションである Worksheets 取得
- Excel の Worksheets から先頭のシート Worksheet 取得
- シート内の処理を行う
- Workbook オブジェクトによりファイルに保存
- Worksheet オブジェクトの解放
- Worksheets オブジェクトの解放
- Workbook オブジェクトを閉じてから解放
- Workbooks オブジェクトの解放
- Excel オブジェクトを閉じる
- Excel アプリケーションの解放
以下の様にオブジェクトを順を追って参照を取得し、対象となるワークシートに処理を行った後で 逆順でオブジェクトの解放を行います。
Excel.Application ⇒ Workbooks ⇒ Workbook ⇒ Worksheets ⇒ Worksheets
オブジェクトの解放用の関数は、Marshalクラスの COM オブジェクトの解放用関数 System.Runtime.InteropServices.Marshal.ReleaseComObject を使います。 (エクセルオブジェクトは COM オブジェクトとして動作するためです)
簡単なエクセル処理の例1
Imports Microsoft.Office.Interop Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Excel のアプリケーション参照用オブジェクト Dim xlsApplication As Excel.Application = Nothing 'Excel の Workbooks 参照用オブジェクト (Workbook の Collection) Dim xlsWorkbooks As Excel.Workbooks = Nothing 'Excel の Workbooks 内の1個の Workbook 参照用オブジェクト Dim xlsWorkbook As Excel.Workbook = Nothing 'Excel の Workbook 内の Worksheets 参照用オブジェクト (Worksheet の Collection) Dim xlsWorkSheets As Excel.Sheets = Nothing 'Excel の Sheets 内の1個の Worksheet 参照用オブジェクト Dim xlsWorkSheet As Excel.Worksheet = Nothing 'Excel の Sheet 内の1個のセル Range 参照用オブジェクト Dim xlsRange As Excel.Range = Nothing 'フルパスでのファイル名 (ファイル名のみだと Excel 側のデフォルトのフォルダになるはず) Dim strFileName As String = My.Application.Info.DirectoryPath & "\test.xlsx" 'Excel アプリケーション起動 xlsApplication = New Excel.Application 'Excel の Workbooks 取得 xlsWorkbooks = xlsApplication.Workbooks 'Excel非表示 xlsApplication.Visible = False xlsApplication.DisplayAlerts = False '既存 Excel ファイルを開く xlsWorkbook = xlsWorkbooks.Open(strFileName) 'Excel の Worksheets 取得 xlsWorkSheets = xlsWorkbook.Worksheets 'Excel の Worksheet 取得 xlsWorkSheet = CType(xlsWorkSheets.Item(1), Excel.Worksheet) 'シート名称 xlsWorkSheet.Name = "シート名test" 'セル選択 xlsRange = xlsWorkSheet.Range("A1") 'セルに値設定 xlsRange.Value = "TEST123" MRComObject(xlsRange) '保存時の問合せダイアログを非表示に設定 xlsApplication.DisplayAlerts = False 'ファイルに保存 (Excel 2007~ブック形式) xlsWorkbook.SaveAs(Filename:=strFileName, FileFormat:=Excel.XlFileFormat.xlOpenXMLWorkbook) '保存時の問合せダイアログを表示に戻す xlsApplication.DisplayAlerts = True '終了処理 'xlsWorkSheet の解放 MRComObject(xlsWorkSheet) 'xlsWorkSheets の解放 MRComObject(xlsWorkSheets) 'xlsWorkbookを閉じる xlsWorkbook.Close(False) 'xlsWorkbook の解放 MRComObject(xlsWorkbook) 'xlsWorkbooks の解放 MRComObject(xlsWorkbooks) 'Excelを閉じる xlsApplication.Quit() 'xlsApplication を解放 MRComObject(xlsApplication) End Sub 'COM オブジェクトへの参照を解放 Private Sub MRComObject(ByRef objCom As Object) If Not objCom Is Nothing Then Try System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom) Catch ' Finally '参照を解除する objCom = Nothing End Try End If End Sub End Class
各処理の途中でエラーが発生した場合には COM オブジェクトの解放が行われない場合がありますので、 変数の宣言以降を Try … Catch … End で括って更に終了処理を Finally にまとめて以下の様にすれば解消できるはずです。
簡単なエクセル処理の例2
Imports Microsoft.Office.Interop Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Excel のアプリケーション参照用オブジェクト Dim xlsApplication As Excel.Application = Nothing 'Excel の Workbooks 参照用オブジェクト (Workbook の Collection) Dim xlsWorkbooks As Excel.Workbooks = Nothing 'Excel の Workbooks 内の1個の Workbook 参照用オブジェクト Dim xlsWorkbook As Excel.Workbook = Nothing 'Excel の Workbook 内の Worksheets 参照用オブジェクト (Worksheet の Collection) Dim xlsWorkSheets As Excel.Sheets = Nothing 'Excel の Sheets 内の1個の Worksheet 参照用オブジェクト Dim xlsWorkSheet As Excel.Worksheet = Nothing 'Excel の Sheet 内の1個のセル Range 参照用オブジェクト Dim xlsRange As Excel.Range = Nothing 'フルパスでのファイル名 (ファイル名のみだと Excel 側のデフォルトのフォルダになるはず) Dim strFileName As String = My.Application.Info.DirectoryPath & "\test.xlsx" Try 'Excel アプリケーション起動 xlsApplication = New Excel.Application 'Excel の Workbooks 取得 xlsWorkbooks = xlsApplication.Workbooks 'Excel非表示 xlsApplication.Visible = False xlsApplication.DisplayAlerts = False '既存 Excel ファイルを開く xlsWorkbook = xlsWorkbooks.Open(strFileName) 'Excel の Worksheets 取得 xlsWorkSheets = xlsWorkbook.Worksheets 'Excel の Worksheet 取得 xlsWorkSheet = CType(xlsWorkSheets.Item(1), Excel.Worksheet) 'シート名称 xlsWorkSheet.Name = "シート名test" 'セル選択 xlsRange = xlsWorkSheet.Range("A1") 'セルに値設定 xlsRange.Value = "TEST123ABC" MRComObject(xlsRange) '保存時の問合せダイアログを非表示に設定 xlsApplication.DisplayAlerts = False 'ファイルに保存 (Excel 2007~ブック形式) xlsWorkbook.SaveAs(Filename:=strFileName, FileFormat:=Excel.XlFileFormat.xlOpenXMLWorkbook) '保存時の問合せダイアログを表示に戻す xlsApplication.DisplayAlerts = True Catch ex As Exception MsgBox(ex.Message) Finally '終了処理 'xlsWorkSheet の解放 MRComObject(xlsWorkSheet) 'xlsWorkSheets の解放 MRComObject(xlsWorkSheets) 'xlsWorkbook のオブジェクトが存在すれば閉じる If Not xlsWorkbook Is Nothing Then xlsApplication.DisplayAlerts = False xlsWorkbook.Close() xlsApplication.DisplayAlerts = True End If 'xlsWorkbook の解放 MRComObject(xlsWorkbook) 'xlsWorkbooks の解放 MRComObject(xlsWorkbooks) 'xlsApplication のオブジェクトが存在すれば閉じる If Not xlsApplication Is Nothing Then xlsApplication.DisplayAlerts = False xlsApplication.Quit() xlsApplication.DisplayAlerts = True End If 'xlsApplication を解放 MRComObject(xlsApplication) End Try End Sub 'COM オブジェクトへの参照を解放 Private Sub MRComObject(ByRef objCom As Object) If Not objCom Is Nothing Then Try System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom) Catch ' Finally '参照を解除する objCom = Nothing End Try End If End Sub End Class
関連する記事
⇒access vba でWordを起動しファイル保存時のファイル名変更について(DocumentBeforeSave : Word保存前イベント)
⇒access vba でExcelを起動しファイル保存でのファイル名変更について(WorkbookBeforeSave : Excel保存前イベント)
⇒access vba でのWord処理用クラスの作成(ファイル保存時イベント[DocumentBeforeSave]でのファイル名変更処理を含む)
⇒access vba でのWord文書の文字列検索と置換について(Word処理用クラスに文字列置換関数を追加)
⇒access vba Bookmarkオブジェクトで文書の先頭にカーソルを移動する(Word処理用クラスに文書の先頭移動関数を追加)