次々に質問で申し訳ないのですが。
VB2008で動く物をVB6に移植しようと思いますが、
Dim xlApp As Excel.Application
でユーザー定義型は定義されていませんとのエラー出力があります。
'Excel本体表示、マクロ実行、Excel本体残し
Private Sub Command1_Click()
Dim er_f As Boolean
Call Excel_exe(False, False, "c:\test.xls", "auto_open", False, er_f)
MsgBox (er_f)
End Sub
'Excel本体非表示、マクロ実行、Excel本体消去
Private Sub Command2_Click()
Dim er_f As Boolean
Call Excel_exe(True, False, "c:\test.xls", "auto_open", True, er_f)
MsgBox (er_f)
End Sub
'Excelを起動指定して起動する。
'****************
'hide=true Excel本体を隠すか?
'err_f=true Excelの警告、メッセージ表示?
'file_pn= "c:\tmp\*.xls 開くファイルパスとファイル名
'exe_mn= "auto_open" 実行するマクロ名
'Excel_end=true 最後にExcel本体を終了するか?
'exe_err=true 実行結果のエラー返し
Private Sub Excel_exe(ByVal hide_f As Boolean, ByVal err_f As Boolean, ByVal file_pn As String, ByVal exe_mn As String, ByVal Excel_end As Boolean, ByVal exe_err As Boolean)
Dim xlApp As Excel.Application
Dim xlbook As Excel.Workbook
On Error GoTo Er1
' Excelのインスタンス作成
xlApp = CreateObject("Excel.Application")
' Excelの表示有無
If hide_f = True Then
xlApp.Visible = False
Else
xlApp.Visible = True
End If
' マクロの警告やメッセージを表示するか?
If err_f = True Then
xlApp.DisplayAlerts = True
Else
xlApp.DisplayAlerts = False
End If
' 指定したExcelファイルを開く
If file_pn <> "" Then
xlbook = xlApp.Workbooks.Open(file_pn)
Else
'Excelを通常起動する。
xlbook = CType(xlApp.Workbooks.Add, Excel.Workbook)
End If
' マクロの実行
If exe_mn <> "" Then
xlApp.Run (exe_mn)
End If
' Excelの終了
If Excel_end = True Then
xlApp.Quit()
End If
' オブジェクトを解放
xlbook = Nothing
xlApp = Nothing
exe_err = False
Exit Sub
Er1:
' エラーメッセージを表示
exe_err = True
End Sub
メニューバーの
プロジェクト(P)
参照設定(N)
で
Microsoft Excel XXX ObjectLirary
にチェックを入れる
ない場合はあきらめる。
> ユーザー定義型は定義されていません
そふと99さんの書き込みのとおりです。
参照設定行ってください。
ちなみに、VB6で動かすには
このエラー以外にもエラーだらけです。
> xlApp = CreateObject("Excel.Application")
Set xlApp = CreateObject("Excel.Application") が正解
> xlbook = xlApp.Workbooks.Open(file_pn)
こちらも Set が必要
> xlbook = CType(xlApp.Workbooks.Add, Excel.Workbook)
この「CType」って何ですか?VB6にはないと思います。
> xlApp.Quit()
xlApp.Quit が正しい
オブジェクトを解放する際も Set が必要です。
下記サイトに、VB6でエクセルを扱う方法が書かれています。
ご参考まで。
ttp://hanatyan.sakura.ne.jp/vbhlp/excelframe.htm
エクセルとは関係ない部分ですが、もう少しプログラムを
改良できると思います。
たとえば、
If hide_f = True Then
xlApp.Visible = False
Else
xlApp.Visible = True
End If
としていますが、
xlApp.Visible = Not hide_f
とすればいいのではないでしょうか?
あと引数を ByVal にする必要はないのでは?
ByRef と ByVal の違いはわかりますか?
それ、参考にしている .NET 用のコードに問題がありますよ。
動く事は動くと思いますが、VB6 向けコードを、そのまま VB.NET に翻訳しただけのような
作りになっていて、VB.NET として使うには、いろいろと問題のあるコードになっています。
(オブジェクトの解放処理が無く、単に Nothing を代入しているだけとか、
参照設定しているのに CreateObject しているとか。細かいところでは、
CType よりも DirectCast を使う方が望ましい、とか。)
まぁ、それゆえに VB6 に翻訳しやすいコードである、とも言えますが。
>> Dim xlApp As Excel.Application
>> でユーザー定義型は定義されていませんとのエラー出力があります。
この場合は、その変数定義を As Object にするだけで OK です。
ついでに、モジュールの先頭に「Option Explicit」も入れておきましょう。
一応、VB6 で Excel を参照設定すれば "As Excel.Application" を利用できますし、
参照設定した方が本来は望ましいです。
しかし参照設定すると、「親オブジェクトを指定せずに、シートやセルを利用する」といった
“誤ったコード”を書いたときに、2 回目以降の Excel 操作が失敗するようになったり、
Excel が終了しなくなるといった、気づきにくい問題を抱える可能性があります。
http://homepage1.nifty.com/rucio/main/technique/teq_15.htm
参照設定しなかった場合は、そのような親オブジェクトを指定しないコードは
「変数が宣言されていません」のエラーとなるため、“誤ったコード”が
混入することを防げます。
なので VB6 から操作するのであれば、まずは参照設定無しで始めるというのも一つの手です。
(.NET の場合は、逆に参照設定しない事によるデメリットの方が大きいのですが…)
>> xlbook = CType(xlApp.Workbooks.Add, Excel.Workbook)
> この「CType」って何ですか?VB6にはないと思います。
型変換のための関数です。
VB6 の場合、オブジェクトをキャストする場合には、目的の型の
変数を用意して、そこに代入する必要があります。
http://support.microsoft.com/kb/168830/ja
つまりこの場合、変数のキャストを行う場合には
Dim xlBook As Excel.Workbook
に対して、
Set xlBook = xlApp.Workbooks.Add()
というコードを書けばよいことになります。型変換の関数は不要です。
> あと引数を ByVal にする必要はないのでは?
> ByRef と ByVal の違いはわかりますか?
それは逆でしょう。
ByVal で良い——というよりも、ByValにするべき——だと思いますよ。
(ByVal / ByRef を省略した場合、VB6 では ByRef、VB.NET では ByVal の意味になります)
ByVal の場合、プロシージャ内で引数が指す物が入れ替わらない事が保証されます。
今回のようなパターンでは、ByRef にするメリットは殆どありません。
VB6 で ByRef を「使わなければならない」パターンとは、
・ByVal では渡せない型を引数にする場合(ユーザー定義型)
・プロシージャ内で引数を書き換える必要がある場合
・ByVal として宣言することが許可されていないイベントプロシージャを利用する場合
などに限られます。
それ以外の場合、VB6 で意図的に ByVal/ByRef を記述するのであれば、極力、ByVal を選択するべきかと。
魔界の仮面弁士さま
訂正ありがとうございます。
知識が豊富で尊敬しております。
> ByVal の場合、プロシージャ内で引数が指す物が
> 入れ替わらない事が保証されます。
> 今回のようなパターンでは、ByRef にするメリットは殆どありません。
たしかにそうなのですが、このプログラムは
VB.net から VB に変換済みのコードではないのですね。
>VB2008で動く物をVB6に移植しようと思いますが、
>Dim xlApp As Excel.Application
>でユーザー定義型は定義されていませんとのエラー出力があります。
とあったので、既にVB6に変換済みでVB6で動かしたと思ってました。
なので「ん?」と思ったわけです。
意図的に書くのであれば ByVal を選択すべきと私も思いますが、
このプログラムでは意図的に書いたとは思えなかったので・・・
皆さんご回答頂きましたが私にはこの件VB6に変換するのは
無理と判断し、再勉強してみますので、この場は一応
かってとは思いますが、解決とさせて頂きます。
再度別に質問させてもらいます。
大変ご迷惑をおかけしますが、その時は宜しく願います。
すみません仮解決です。
ツイート | ![]() |