- 締切済み
VB6.0 ExcelオブジェクトのFind操作について
VB6.0にてExcelよりデータの取り込み処理を 行っております。 その際に、ある指定の文字列が現れる最初の行を取得する 処理があるのですが、下記処理でインストールされている Excelのバージョンにより、エラーになってしまいます。 ====Excel2000の場合OK。 Excel2003の場合NG。===== '最終行を取得する。 Set ObjFR = .Columns(1).Find("終了") intMaxRow = ObjFR.Row ====Excel2003の場合OK。 Excel2000の場合NG。===== '最終行を取得する。 Set ObjFR = .Cells(1).Find("終了") intMaxRow = ObjFR.Row 上記、処理においてバージョンに依存せずに回避する方法が ありましたらお教え頂きたいと思います。 宜しくお願いいたします。
- みんなの回答 (9)
- 専門家の回答
みんなの回答
- KenKen_SP
- ベストアンサー率62% (785/1258)
ん、、伝わらないので、はっきり言いますね。 > 上記の場合でもColumnsをCellsにすれば動作します。 それはタマタマであって....バージョンに依存せずに回避する方法知りたいなら 偶然に依存するコードではダメだと思いますよ。 Find メソッドのヘルプを読みましたか? #8 に書きましたが、Find は見つからないと Nothing を返します。つまり、 Nothing 時のエラートラップが必要なので、明らかにエラーの原因は単純な コーディングミスです。 こういったメソッドの仕様について、#7 で示唆しているのだから > ColumnsをCellsにすれば動作します。 このような反証よりもまず、ヘルプを読むべきかと。そこに Nothing を返す ことも書いてあるのだから、それで解決するはずですけど... もう退散します。dsuekichi さん、お邪魔して申し訳ありません。
- KenKen_SP
- ベストアンサー率62% (785/1258)
追加補足。 #7 に書いた様に、検索対象が違うなどが原因となって意図したセルが検索され ないケースは多いです。 このとき、「 Find は Nothing 」を返します。 また、 RangeObj.Find(~) としたときは、RangeObj の範囲で検索します。つまり、 With objExcelBook.Worksheets("シート名") Set ObjFR = .Cells(1).Find("終了") ~ End With は A1 セルだけ検索して終了しますので、A1 セルが「終了」でなければ、 Find は Nothing を返します。となると、ObjFR.Row は当然エラーです。
補足
上記Cellsの場合でObjFR.Rowが527(行数)という値が 取得できています。 Columnsにした場合、何を設定してもNothingが返ってきてしまいます。 記載しているプログラムは下記のとおりです。 '1 Set ObjFR = .Columns(1).Find(What:="終了", _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchOrder:=xlByRows, _ MatchByte:=False) .Columns("A").Select '2 Set ObjFR = .Cells(1).Find(What:="終了", _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchOrder:=xlByRows, _ MatchByte:=False)
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。 > バージョンに依存せずに回避する方法.... 多分 Find の使い方が悪いのですよ。ヘルプを引用します。 -------------------------------------------------------------- 引数 LookIn、LookAt、SearchOrder、および MatchByte の設定は、 このメソッドが使われるたびに保存されます。 次にこのメソッドを使うときに、これらの引数の指定を省略すると、 保存された設定が使われます。 これらの引数の設定を変更すると、[検索と置換] ダイアログボックス に表示される設定が変わります。 -------------------------------------------------------------- したがって、Find の使い方は、 Set ObjFR = .Columns(1).Find(What:="終了", _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchOrder:=xlByRows, _ MatchByte:=False) ※注:参照設定してる場合のコードです。 みたいに面倒でも検索オプションを「明示的に指定」する必要があります。 つまり、環境が違えば、[検索と置換] ダイアログボックスに予め設定された 検索オプションが違う可能性がありますよね? 例えば、検索場所が「セル」だったり「数式」だったり。 上記のことを仮定すると、バージョンにより Find の結果が異なるように 見えた質問者、対して、通常一つの環境でしかテストしない回答者側では 再現しない...という行き違いが納得できるのですが、どうですか?
お礼
上記の場合でもColumnsをCellsにすれば動作します。 他にも要因があるのかもしれません。 もう少しこちらでも調査して見ます。 色々と有難う御座います。
- dsuekichi
- ベストアンサー率64% (171/265)
・・・半分再現しました。 500行のExcelで Windows2000+Excel2000 WindowsXP+Excel2003 の環境で試してみました・・・ 結果、 > Set ObjFR = .Columns(1).Find("終了") は、Excel2000/Excell2003のどちらでもOK > Set ObjFR = .Cells(1).Find("終了") は、Excel2000/Excel2003のどちらもNG でした・・・ Excelのバージョン依存と言うより、データ依存の様な・・・ でも、使用しているデータは同じファイルなんですよね?
お礼
おっしゃるとおり、原因はデータ依存でした。 セルが結合されていたため、データが取得できていなかったようです。 お忙しいところ本当に有難う御座いました。
補足
同じExcelファイルです。 他端末(環境)でも調査してみます。
- dsuekichi
- ベストアンサー率64% (171/265)
追記 ついでに > objExcelApp.DisplayAlerts = False も止めてみてください。 #他にも、通常動作を妨げる設定があるなら、全部一時的に止めてみてください。
補足
回答有難う御座います。 Excelの内容はA列の500行目に指定文字「終了」が記載されており、 他の行は一覧表(計画表)のように記載されている一般的な Excelシートです。 他処理でエラーは起きていないため、Error処理を止めても状況は 変わりません。 DisplayAlertsを止めても状況は変わりません。
- dsuekichi
- ベストアンサー率64% (171/265)
> Excelファイルのセルの内容 こちらはどうなっていますか? 何列x何行のデータで、空白セル有りor無し、"終了"がどこのセルにある。 等でも良いです。 何か特徴がありますか? #行数が無茶苦茶多いとか、空白が多いとか・・・ > 上記のintMaxCnt = ObjFR.Rowでエラーになります。 > 「オブジェクト変数または With ブロック変数が設定されていません。」 これは、どうやって確認したんでしょうか? VB6を2台のPC(Excel2000がインストールされたPCとExcel2003がインストールされたPC)にインストールして、各々確かめた? それから、 > On Error GoTo ExcelErrHandler がありますが、これを止めたら、どうなります? #別の箇所でエラーになっていたりしませんか?
- dsuekichi
- ベストアンサー率64% (171/265)
うーん。私の環境では再現しませんね・・・ #WindowsXP(SP2),Office2003(SP2),VB6(SP5) 再現試験をやってみたいんですが・・・ 差し支えない範囲でExcelファイルのセルの内容と、 実際のプログラムを提示できませんでしょうか? #余分な部分を削って、状況が発生するできるだけ短いコードで・・・ 後、Windowsのバージョンとか、SPの適用とかはどうなっていますか?
補足
すばやいご返答有難う御座います。 実際のプログラム(該当箇所まで)は下記になっています。 Dim objExcelApp As Object 'エクセルアプリ Dim objExcelBook As Object 'エクセルブック Dim ObjFR As Object Dim intMaxCnt As Integer 'オブジェクトの設定 Set objExcelApp = CreateObject("Excel.Application") Set objExcelBook = objExcelApp.Workbooks.Open("Excelファイルのパス") 'エクセルへ参照 On Error GoTo ExcelErrHandler '保存の確認ダイアログ非表示設定 objExcelApp.DisplayAlerts = False 'Excelを開く With objExcelBook.Worksheets("シート名") '最終行を取得する。 Set ObjFR = .Columns(1).Find("探索文字") intMaxCnt = ObjFR.Row End With 上記のintMaxCnt = ObjFR.Rowでエラーになります。 「オブジェクト変数または With ブロック変数が設定されていません。」 Windowsは2000,2003ともにXP SP2です。
- dsuekichi
- ベストアンサー率64% (171/265)
> バージョンによって、ObjFRがNothingになってしまいます。 本当に、バージョンが原因ですか? 少なくとも、私のExcel2003では、ちゃんとHITします。 #Nothingにはなりません。 本当に、対象文字が無いのでは? 例えば、「HITするはずのセル」がCells(a,b)だとして、 > Set ObjFR = .Columns(1).Find("終了") の前で、 > MsgBox(.Cells(a,b)) とすると、「終了」とかが表示されますか?
補足
原因がバージョンかどうかは分かりませんが、 開発環境の違いは2003と2000の違いしか考えられません。 >> MsgBox(.Cells(a,b)) >とすると、「終了」とかが表示されますか? されます。 cellsとColumnsを変更すると正しく動作するので対象文字が 無い事はありません。
- dsuekichi
- ベストアンサー率64% (171/265)
> ====Excel2000の場合OK。 Excel2003の場合NG。===== > '最終行を取得する。 > Set ObjFR = .Columns(1).Find("終了") > intMaxRow = ObjFR.Row Excel2003で実行してみましたが・・・エラーにはなりませんけど・・・ ちなみに、「.Columns(1)」の前は(多分Withで指定しているはずですが)何なのでしょう? ちゃんと、該当Sheetを指定していますか?
補足
早速のご返答ありがとうございます。 With objExcelBook.Worksheets("シート名") でシートの記述を行っています。 バージョンによって、ObjFRがNothingになってしまいます。
補足
>> ColumnsをCellsにすれば動作します。 >このような反証よりもまず、ヘルプを読むべきかと。そこに Nothing を返す >ことも書いてあるのだから、それで解決するはずですけど... 反証してるわけじゃないですけどね... ヘルプを見てNothingが返ることも分かっています。 ただ、Columns・Cellsの記述で動作する原因が分からないままだと 今後にも問題かと思いまして調査していました。 お忙しいところどうもありがとうございました