• ベストアンサー

EXCELのマクロからDLLをコール

EXCELのマクロからDLL内部の関数をコールしたいのですが、うまくいきません。 DLLは、BCC DeveloperとBorland C++ Builer 5を使って作りました。DLLのソースは以下の通りです。 dlltest.cpp ===================================== #include <stdio.h> extern "C" long __stdcall put_sen(char *sen_area) { strcpy(sen_area, "Hello world!"); return 0; } ===================================== EXCELのマクロは以下の通りです。 ===================================== Declare Function put_sen Lib "dlltest.dll" (ByVal sen_area As String) As Long Sub test() Dim sen_area As String Dim rtn As Long t_st = ActiveWorkbook.Path ChDrive Left(t_st, 1) ChDir t_st rtn = put_sen(sen_area) MsgBox sen_area End Sub ===================================== これで、EXCELファイルとDLLファイルを同じフォルダに入れて、マクロを実行すると、 実行時エラー'453' エントリ put_sen が DLLファイル dlltest.dll 内に見つかりません。 とエラーが表示されます。 以前、VC++でDLLを作った際には、これでうまくいったと思うのですが…。 どこがいけないのか、どなたかご教授よろしくお願いします。 ちなみにOSはWindows2000です。

noname#22592
noname#22592

質問者が選んだベストアンサー

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.5

>extern "C" __declspec(dllexport) long __stdcall put_sen(char *sen_area){ > >としてみて下さい。 bccはこれだけではだめです。 関数名の先頭にアンダースコアが修飾されてしまいます。 __declspec(dllexport)をつけるときは、コンパイル時に-u-オプションを指定する必要があります。

その他の回答 (4)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

型の話は、勘違いでした。 extern "C" __declspec(dllexport) long __stdcall put_sen(char *sen_area){ としてみて下さい。 sen_areaを確保しておかなければならないのは、#3の方と同じです。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

>エントリ put_sen が DLLファイル dlltest.dll 内に見つかりません。 DLL内にput_senが見つからないというエラーですよね。 DLLそのものは検索されています。 >dlltest.cpp C++ですよね。 defファイル作らないと関数名がbccによって変えられてしまいます。 Rubyから呼ぶときですが、defの作り方は一緒です。 http://gimite.ddo.jp/behind/bcbrubyext.htm >型が違うからではないでしょうか? 型は問題ないです。 ですが、DLL作り直しても使い方が >rtn = put_sen(sen_area) ではまずいです。 あらかじめ、VBA側で領域を確保する必要があります。 sen_area = Space(256) rtn = put_sen(sen_area) また、DLLより取得された文字列はNULL終端の文字列なので、VBA側でNULL文字を削除する必要があります。 #まぁ、MsgBoxで表示するだけなら問題ありませんが。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

型が違うからではないでしょうか? VBAでのStringとCでのchar*で型が異なるから。 Cの方でバリアントのストリングを使うとか

noname#22592
質問者

お礼

ご回答、ありがとうございます。 すいませんが、 >Cの方でバリアントのストリングを使う という意味がいまいちわかりません…。 ちなみに、このC++のソースをVC++でコンパイルするとうまくいきました。 以前はVC++を持っていたのですが、今は持っていないため、BCBを使っております。 BCBだとおっしゃる部分が問題になるのでしょうか??

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.1

> これで、EXCELファイルとDLLファイルを同じフォルダに入れて、マクロを実行すると、 同じように、ローカルで上手く探してくれなかった事がありました。 dllファイルを、 C:\WINNT C:\WINNT\system32 に置いた場合はどうでしょうか?

noname#22592
質問者

お礼

状況は変わりませんでした。 ご検討、ありがとうございました。

関連するQ&A

  • エクセルでのマクロ

    学校の授業で、エクセルのマクロ(VBA)を習っています。 そこで、質問なんですけど、 Dim ???? As Long Dim ???? As String というように????のところが異なる文字をおいたりして変数を定義するのはわかったのですが、なぜLong とStringと異なるものを使うのでしょうか?同じでも問題はないのでしょうか?教えてください。

  • エクセル2000マクロエラー

    下記のマクロを記述を記載していますが Open path + finame For Input As #1→でファイルがありませんという エラーがでます。c:\aa着色加工計画\testにファイル(T_Sort.csv)はあるみたいなのですが 教えてください。何が原因でしょうか Sub Do_shukei() Dim 処方(1) As String, 品名(1) As String Dim 倉庫(1) As String Dim tuki(15) As String, sort(1) As String, st As Integer Dim sihan(8) As Long, zaiko As Long, suryo(15) As Long Dim ryo(6) As Long, a As Integer, i As Integer Dim path As String, finame As String, foname As String st = 1 a = 1 For i = 1 To 15 suryo(i) = 0 Next i path = "c:\aa着色加工計画\test" finame = "T_Sort.csv" foname = "T_shukei.csv" Open path + foname For Output As #2 Open path + finame For Input As #1 Do Until EOF(1) = True If a = 1 Then Input #1, sort(0), 倉庫(0), 処方(0), 品名(0), tuki(1), tuki(2), tuki(3), tuki(4), tuki(5), tuki(6), tuki(7), tuki(8), tuki(9), tuki(10), tuki(11), tuki(12), tuki(13), tuki(14), tuki(15) Write #2, sort(0), 倉庫(0), 処方(0), 品名(0), tuki(1), tuki(2), tuki(3), tuki(4), tuki(5), tuki(6), tuki(7), tuki(8), tuki(9), tuki(10), tuki(11), tuki(12), tuki(13), tuki(14), tuki(15) a = 0 GoTo l 下記省略

  • アクセスからエクセルのマクロを実行したいのですが

    Sub エクセルのVBA実行する() Dim xlsWB As Object Dim MyFileName As String MyFileName = "C:\test.xlsx" Set xlsWB = GetObject(MyFileName) xlsWB.Application.Run xlsWB.Name & "!マクロ" Set xlsWB = Nothing End Sub と言うコードを作ったのですが エクセルファイルにはパスワードがかかっています。 パスワード付のエクセルファイルを開きマクロを実行するにはどうすればいいでしょうか?

  • Excelマクロについて教えてください。

    Excelマクロについて教えてください。 フォルダ内にある全てのファイルのA列にAを追加したいのですが、 下記だとA1にAを上書きしてしまいます。 book.Sheets(1).Range("A1") = "A" '最初のシートのA1に"A"を フォルダ内のファイルのA列に値がある場合、Aを追加する場合のマクロを教えてください。 例) test.xls A列 →A列 12345 →A12345 55555 →A55555 Sub sample() Dim dataFolder As String Dim file As String Dim book As Workbook Dim fileName As String Dim fileExt As String dataFolder = "C:\test\" 'excelがあるフォルダ file = Dir(dataFolder & "*.xls") '最初のexcelファイル名 Do While file <> "" 'ファイル名がある間 '内容変更 Set book = Workbooks.Open(dataFolder & file) 'ブックを開く book.Sheets(1).Range("A1") = "A" '最初のシートのA1に"A"を book.Close True '上書きして閉じる file = Dir '次のファイル名 Loop '繰り返す End Sub 教えてください。

  • 教えて★ExcelでVBのマクロについて

    以前ここで質問させていただきました。 http://okwave.jp/qa3029622.html 上の内容のとおり教えていただきました。 マクロにさらにタイトルを追加したいのですが可能でしょうか? ファイルAのタイトルは5行目から始まり8行目まであります。 ファイルBのタイトルは2行目から始まり6行目まであります。 ★ファイルAのタイトルにファイルBのタイトルをつけ加えたい! 以下のソースに付け加えるとしたら、どこにどのように追加すればよいですか? 以上ですがよろしくお願いいたします。 Sub findJoin() On Error GoTo err Dim st1 As Worksheet Dim st2 As Worksheet Set st1 = ActiveSheet Workbooks.Open ("870xtd.xls") Set st2 = Workbooks("870xtd.xls").Sheets(1) Dim st1MaxRow As Long Dim st2Maxrow As Long st1MaxRow = st1.Cells(st1.Rows.Count, "A").End(xlUp).Row st2Maxrow = st2.Cells(st2.Rows.Count, "AB").End(xlUp).Row Dim R As Long For R = 2 To st1MaxRow Dim nmRng As Range Set nmRng = st2.Range("AB2:AP" & st2Maxrow).Find(st1.Cells(R, "A").Value, LookIn:=xlValues) If Not nmRng Is Nothing Then '発見した。 st2.Range("A" & nmRng.Row & ":AP" & nmRng.Row).Copy Destination:=st1.Range("DQ" & R) End If Next st1.Activate Set st1 = Nothing Set st2 = Nothing Exit Sub err: MsgBox Error End Sub

  • Excel マクロ ファイル名取得について

    Excel マクロ ファイル名取得について 特定のフォルダにあるファイルのファイル名を Excelに一覧として作成します。 下記マクロで実現できたのですが、フォルダでファイルを 「詳細」で並べて上から順番にB列に反映することは 可能でしょうか。 ご回答お待ちしております。 Sub fileName() Dim MyF As String Dim myRow As Long 'ファイル名の取得 myRow = 2 MyF = Dir(ThisWorkbook.Path & "\*") If MyF <> "" Then Do Until MyF = "" Cells(myRow, "B").Value = MyF 'ファイル名 MyF = Dir() myRow = myRow + 1 Loop End If End Sub

  • AccessVBAからC言語のDLLの呼び出し方

    初心者です。はじめまして お世話になります。 概要:C言語で作成したDLLをVBAで呼び出す。 タイトルの通り、C言語で作成したDLLをVBAで呼び出したいのですが、うまく 呼び出すことができず、「エラー番号:49 DLLを正しく呼び出せません。」 というエラーが返ってきてしまいます。 DLLの作成手順もしくはDLLの呼び出し方でおかしな所があればご指摘頂けない でしょうか? C言語のDLL、作成手順は以下の通りです。 DLL作成環境:Visual C++ 6.0 DLL作成手順----------------------------------------- (1)プロジェクトをDLL用に作る  新規作成→プロジェクト→Win32 Dynamic-Link Library→空のDLLプロジェ クト (2)ファイル追加  ソースファイル+すべてのヘッダファイルを追加 (3)DLLを出力対象の関数に「_declspec(dllexport)」をつける 例)------------------------------------- _declspec(dllexport) short dlltest (char *str1, char *str2) --------------------------------------- (4)char を unsigned char へ変換する(/J コンパイルオプション) (5)プロジェクトをデバッグモードからリリースモードに切り替える (6)ビルド実行 (7)「Release」配下に.dllとlibができる。 -作成手順完----------------------------------------------------- 実際のVBAのDLLの呼び出しは以下の通り行っています。 -AccessVBAにてDLLの宣言及び、呼び出し------------------- '呼び出し宣言 Public Declare Function dlltest _ Lib "C:\Project\Dlltest\Release\dlltest.dll" _ (ByVal st1 As String, _ ByVal st2 As String) As Integer 'DLL呼び出し KEKKA = dlltest(string1, string2) -呼び出し完------------------------------------------------ これで実行するとエラーが返されていまいます。 なにぶん、初心者で今回初めてVBAでのプログラミングを行っているので観点 の抜けなどが多分にあると思われます。 どんな小さなことでもご指摘頂けないでしょうか? 宜しくお願い致します。

  • excelのマクロで音声の停止と再生

    excelのマクロでいくつかのwavファイルを音声再生途中で一時停止と、その途中からの音声再生はどのようにすればよいのでしょうか? Declare Function PlaySound Lib "Winmm.dll" Alias "PlaySoundA" _ (ByVal pszSound As String, _ ByVal hmod As Long, _ ByVal fdwSound As Long) As Long Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Public Const SND_ASYNC = &H1& '再生後すぐに制御を戻す Public Const SND_SYNC = &H0& '再生が完了するまで制御を戻さない Private Function MusicLength(ByVal FilePath As String) As Date Dim oSH As Object, oFS As Object, oFLD As Object, oF As Object Dim sT As Date Set oSH = CreateObject("Shell.Application") Set oFS = CreateObject("Scripting.FileSystemObject") Set oF = oFS.getfile(FilePath) Set oFLD = oSH.Namespace(oF.ParentFolder.Path) sT = CDate(oFLD.GetDetailsOf(oFLD.ParseName(oF.Name), 27)) MusicLength = sT + #12:00:01 AM# End Function Sub A列再生() Dim En As Long, i As Long Dim INF As String Dim ML As Date, sT As Date En = Range("A65536").End(xlUp).Row For i = 2 To En INF = ThisWorkbook.Path & "\ONSEI\" & Range("A" & i).Value & ".WAV" ML = MusicLength(INF) PlaySound INF, 0, SND_ASYNC ' sT = Now Do Until Now > sT + ML Sleep 100

  • マクロでhtml出力?

    先日、マクロの件で質問した者です。 http://oshiete1.goo.ne.jp/qa4473686.html 良回答のlulさんのコードを参考にしています。 質問1 下記のコードではV列にhtmlが表示されるようになっています。 (エクセルにはAからTまでデータが入っています) 今回はセルV列にhtmlを表示するのではなくエクセルシートが置いてあるフォルダに各htmlを出力したいのですがどこをどのように変更すればいいのでしょうか? (ちなみに、C列にあるものをファイル名とします) 質問2 また、フォルダ名を指定してそのフォルダに出力する場合も教えてください。 よろしくお願いします。 Sub htmlを作成() Const LFeed As String = vbCrLf Dim st As String Dim sht As Worksheet, i As Long, obj Set sht = ActiveSheet '//現在のシートを設定 Dim MaxRow As Long MaxRow = Range("A65536").End(xlUp).Row For i = 1 To MaxRow If Cells(i, 1) <> "" Then Set Grammar = Nothing 'HTML1行ずつ記載 st = "" st = st & "<html lang='ja'>" & LFeed st = st & "<head>" & LFeed st = st & "</head>" & LFeed st = st & "<body>" & LFeed 途中省略 st = st & "</body>" & LFeed st = st & "</html>" & LFeed st = Replace(st, "'", Chr(34), 1, -1, 1) sht.Cells(i, 22).Value = Mid(st, 1, Len(st) - 1) '//結果を V列に入れる(他の場合はそのように変更する) End If Next i End Sub

  • エクセルマクロでファイルを開かず行をしらべたい

    こんにちは! エクセルマクロでファイルを開かず一番下の行を調べたいのですが、どうしたらよいでしょうか? 色々試行錯誤して、下記を組んでみましたが、上手くできませんでした。 test1のエクセルに下記のマクロを入れてあります。 C直下のtestフォルダの中のtest2.xlsのsheet1のファイルを読み込みたいです。 Dim line As Long Dim names As String names = "C:\test\[test2.xls]sheet1" line = ExecuteExcel4Macro("'" & names & "'!R1C1").End(xlUp).Row 「ファイルを開かず一番下の行を調べる」ことができれば、上記のマクロを動くようにするでも、別のマクロを提示するでも構いませんので、アドバイスのほどよろしくお願いいたします。