概要
古いデータに触る機会があると、弊社では否が応でも.xlsと.xlsxが乱舞しています。
それだけならまだいいのですが、VBAでそのどちらにも触れるとなるとちょっと苦労が発生します。
実際にハマった箇所
やりたい事としては、
①VBAでExcelを読み込む
②読み込んだExcelのシートの最終行の行番号を取得する
③その他諸々……。
になるのですが、②でハマってしまいました。
というのも、どうやら.xlsxのファイルであれば正常に取得できるのですが、.xlsのファイルで読み込もうとすると「エラー箇所」のところで実行時エラー:1004が出てしまいました。
'外部のexcelブックを読み込む
Dim strDir As String, strFile As String
Dim xls As New Excel.Application
Dim wb As Workbook, ws As Worksheet
strDir = Application.GetOpenFilename("Excelファイル,*.xls*")
'ファイル名読み取り
strFile = Dir(strDir)
Set wb = xls.Workbooks.Open(strDir)
Set ws = wb.Worksheets(1)
'エラー箇所
Dim R As Long
R = ws.Cells(Rows.Count, "B").End(xlUp).Row
対策
どうやら、.xls側でRowsプロパティを参照にする際はきちんとオブジェクトを指定する必要があるようです。
'修正箇所
Dim R As Long
R = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
普段は.csvや.xlsxしか取り扱わないので、そちらでは動作するのに何故この箇所でエラーが出るのかと悩んでおりました。
具体的に何故.xlsではここまで丁寧に指定しないと動かず、.xlsxや.csvでは動いたのかについては分かっておりません。
詳しい方がいらっしゃれば補足頂けると助かります。
追記
.xlsの最大行数は65536行、.xlsxの最大行数は1048576行となっています。
オブジェクトを指定しなかったときのRows.Countの挙動は、ActiveSheetを参照としますので、今回のエラーの内容としては「.xlsのファイルを開いて1048576行目を参照しようと思ったけど、.xlsにはそんな行数が無かった!!」ということでした。
今まではActiveSheetを指定されようが、.xlsmで実行している限り.xlsmや.csvの行数には支障が無かっただけのようです。
コメント下さった@towa_skm様、ありがとうございます。
おわりに
Python in Excelが発表された日にVBAの記事をUPしているのもなんですが、何はともあれオブジェクトはきちんと定義するに越したことは無いですね。