• ベストアンサー
  • 暇なときにでも

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

共感・応援の気持ちを伝えよう!

  • 回答数5
  • 閲覧数1927
  • ありがとう数3

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

  • ベストアンサー
  • 回答No.5

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

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • エクセルでのマクロ

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

  • 2010 excel マクロ 記号の変化

    エラー発生で強制終了になってしまいます。2007年のexcelで作成したものですが、2010だと強制終了になってしまいます。 内容は□をダブルクリックすると■になるように作っています。 記述は2003年からのマクロ記述なので、変化が必要なのでしょうか? Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) 'Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'セルをダブルクリックすると、・→○→△→×→・と変更する。 Dim S1 As String Dim S2 As String Dim S01 As String Dim S02 As String Dim S03 As String Dim S04 As String S1 = "□" S2 = "■" S01 = "・" S02 = "○" S03 = "△" S04 = "×" On Error GoTo ERR_12 sCheckXY S1, S2 sCheckX1234 S01, S02, S03, S04 sChangeXY S1, S2 Exit Sub ERR_12: End End Sub Sub sChangeXY(X As String, Y As String) '選択セルに□があれば■に変える Dim Str0 As String 'str1の左端 Dim Str1 As String 'strの右側更新 Dim Str2 As String 'strの左側更新 Dim Str20 As String 'strの左側一部保存 Dim L As Long Dim M As Long Dim N As Long Str1 = ActiveCell.Text L = Len(Str1) Debug.Print L If L = 0 Then End End If For N = 1 To L Debug.Print Str2 Str0 = Left(Str1, 1) If Str0 = X Or N = L Then If Str20 <> "" Then If N = L Then Str20 = Str20 + Str0 End If If MsgBox(Str20 & "  はチェックしますか?", vbYesNo, "選択肢") = vbYes Then Str2 = Str2 + Replace(Str20, X, Y) Str20 = Str0 Else Str2 = Str2 + Replace(Str20, Y, X) Str20 = Str0 End If Else Str20 = Str0 End If Else Str20 = Str20 + Str0 End If Str1 = Right(Str1, L - N) Next N ActiveCell.Value = Str2 End Sub Sub sCheckXY(X As String, Y As String) '選択セルがXならY,YならXにチェックをかえる If ActiveCell.Text = X Then ActiveCell.Value = Y End ElseIf ActiveCell.Text = Y Then ActiveCell.Value = X End End If End Sub Sub sCheckX1234(X1 As String, X2 As String, X3 As String, X4 As String) '選択セルがXならY,YならXにチェックをかえる If ActiveCell.Text = X1 Then ActiveCell.Value = X2 End ElseIf ActiveCell.Text = X2 Then ActiveCell.Value = X3 End ElseIf ActiveCell.Text = X3 Then ActiveCell.Value = X4 End ElseIf ActiveCell.Text = X4 Then ActiveCell.Value = X1 End End If 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 教えてください。

その他の回答 (4)

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

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

共感・感謝の気持ちを伝えよう!

  • 回答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で表示するだけなら問題ありませんが。

共感・感謝の気持ちを伝えよう!

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

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

  • 回答No.1

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • 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

  • EXCELで作ったマクロを別のファイルのEXCELでも使えるようにしたいです。

    (1)EXCELファイルでマクロを作成しました。 (実際はここである人の知恵をお借りして作ったものですが…) しかし、(2)EXCELファイルで(1)EXCEL作成マクロが実行できません。 どのような処理をすれば、どのPCでも、どのファイルでも実行できるようなマクロに出来るのでしょうか?? 以下にそのマクロを示します。 ↓↓↓ Sub 文字置換() '半角カタカナを全角に、全角英数を半角にするマクロ (Excel編) Dim rng As Range Dim Re As Object Dim myPat As String Dim c As Range Dim Matches As Object Dim Match As Object Dim Str1 As String Dim Str2 As String Dim buf As String Dim t As Long On Error Resume Next Set rng = ActiveSheet.UsedRange.SpecialCells _ (xlCellTypeConstants, xlTextValues) On Error GoTo 0 If rng Is Nothing Then MsgBox "変換する対象が見当たりません。", 48 Exit Sub End If '全角側 --- 半角側 (!-/ を加えれば記号も半角) myPat = "([\uFF66-\uFF9F]*)([!-}]*)" '正規表現のパターン Set Re = CreateObject("VBScript.RegExp") Application.ScreenUpdating = False With Re .Global = True .IgnoreCase = True .Pattern = myPat For Each c In rng.Cells Set Matches = .Execute(c.Value) If Matches.Count > 0 Then buf = c.Value For Each Match In Matches If Len(Match.Value) > 0 Then Str1 = StrConv(Match.SubMatches(0), vbWide) If Str1 <> "" Then '0 =vbBinaryCompare buf = Replace(buf, Match.SubMatches(0), Str1, , , 0) End If Str2 = StrConv(Match.SubMatches(1), vbNarrow) If Str2 <> "" Then buf = Replace(buf, Match.SubMatches(1), Str2, , , 0) End If End If Str1 = "": Str2 = "" Next Match If buf <> c.Value Then c.Value = buf t = t + 1 End If End If Next c End With Set Re = Nothing Application.ScreenUpdating = True If t > 0 Then MsgBox t & "個のセルを変換しました。", 64 End If End Sub 出来れば、置換した文字数をメッセージBOXに表示したいです。

  • 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

  • エクセルのマクロについて

    エクセル2010を使用しています。 工程表を作成するため、以下のマクロを組もうと苦戦しています。 任意のセルを選択し、マクロを実行すると選択したセルに線を引き 線の上部にテキストボックスで文字を入力できるようにするマクロを 作成しようとしています。 また、テキストボックスは文字入力後、大きさの自動調整をかけようと しています。 線を引くところまでは、うまくいったのですがテキストボックスの挿入→入力待機 →入力後、大きさの自動調整(幅)までのマクロがよくわかりません。 可能であれば、任意の選択したセルの中央に配置をしたいです。 お知恵をお貸しください。よろしくお願いします。 koutei() Dim SentakuTop As Single Dim SentakuLeft As Single Dim SentakuWidth As Single Dim SentakuHeight As Single Dim SentakuAddress As String Dim X0, Y0, X1, Y1 As Variant SentakuAddress = Selection.Address(ColumnAbsolute:=False, RowAbsolute:=False) With ActiveSheet.Range(SentakuAddress) SentakuTop = .Top SentakuLeft = .Left SentakuWidth = .Width SentakuHeight = .Height End With X0 = SentakuLeft Y0 = SentakuTop + SentakuHeight / 2 X1 = SentakuLeft + SentakuWidth Y1 = Y0 With ActiveSheet.Shapes.AddLine(X0, Y0, X1, Y1).Line .ForeColor.RGB = RGB(0, 0, 0) .Weight = 1 .BeginArrowheadStyle = msoArrowheadOval .EndArrowheadStyle = msoArrowheadOval End With End Sub

  • エクセル マクロ ループで?

    度々すいません。マクロはほぼ初心者ですがよろしくお願いします。 前回の質問で、ある程度教えていただいたのですがループさせる方法がよくわかりません。 http://okwave.jp/qa4469670.html サンプルでコードは Sub test()  Dim st As String, s As String, stmp As String  Dim sht As Worksheet, rw As Long, col As Long  st = "<div align='center'><b>$4</b></div>@<div align='center'><a rel='nofollow' href='$8'><img src='$9' border='0' alt='$3'></a></div>@<div align='center'><a rel='nofollow' href='$8'>$3</a></div>@$5@$6@<!--$1$2-->"  st = Replace(Replace(st, "@", Chr(10), 1, -1, 1), "'", Chr(34), 1, -1, 1)  Set sht = ActiveSheet '//現在のシートを設定 '------- 1行分の処理 ----  rw = 2 '//処理対象の行番号(2行目に設定)  s = st '//雛型の文字をコピー  For col = 1 To 9 '//A~I列までをループ(col=列番号)   stmp = "$" & Format(col, "#")    '//各セルの内容で置換え   s = Replace(s, stmp, sht.Cells(rw, col).Text, 1, -1, 1)  Next col  sht.Cells(rw, 14).Value = s '//結果をN列に入れる End Sub です。 マクロを実行するとセルN2に出力されます。これをN2以降、N3N4・・・も表示されるようにしたいです。 rw = 2 '//処理対象の行番号(2行目に設定)を固定させないでループすればいいようなのですが、どのようにすればいいのでしょうか? Sub test()~End Sub内全てを教えていただけないでしょうか? よろしくお願いします。

  • GetWindowText、GetActiveWindowについて

    こんばんは。よろしくお願いします。 まずは以下をご覧ください。 Excel VBA です。 Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Sub Sample() Dim rtn, rtn2 As Long Dim Name As String Dim Leng As Long Dim ReturnValue ReturnValue = Shell("CALC.EXE", 1) AppActivate ReturnValue Sleep 500 Name = String(250, Chr(0)) Leng = Len(Name) rtn = GetActiveWindow() rtn2 = GetWindowText(rtn, Name, Leng) Debug.Print Name End Sub これを実行しても、イミディエイトウインドウに「電卓」は出ません。 エラーもありません。 なぜなのでしょうか?

  • エクセルのマクロで再度質問

    エクセルのマクロの件 再度質問です。 昨日、以下の質問をした者です。 =========================================================================== エクセルにはセルA~Mまでデータが入っています。(件数的にはかなりの量です) そこでマクロを使ってセルN内に以下のようなHTMLを入れたいです。 <div align="center"><b>【Dのセル】</b></div> <div align="center"><a rel="nofollow" href="【Hのセル】"><img src="【Iのセル】" border="0" alt="【Cのセル】"></a></div> <div align="center"><a rel="nofollow" href="【Hのセル】">【Cのセル】</a></div> 【Eのセル】 【Fのセル】 <!--【Aのセル】【Bのセル】--> =========================================================================== そこで、サンプルとして以下のマクロを教えてもらいました。 質問ですが、これを繰り返すにはどうすればいいでしょうか? (N2以降、N3N4・・・も同じように表示するには) Sub test()  Dim st As String, s As String, stmp As String  Dim sht As Worksheet, rw As Long, col As Long  st = "<div align='center'><b>$4</b></div>@<div align='center'><a rel='nofollow' href='$8'><img src='$9' border='0' alt='$3'></a></div>@<div align='center'><a rel='nofollow' href='$8'>$3</a></div>@$5@$6@<!--$1$2-->"  st = Replace(Replace(st, "@", Chr(10), 1, -1, 1), "'", Chr(34), 1, -1, 1)  Set sht = ActiveSheet '//現在のシートを設定 '------- 1行分の処理 ----  rw = 2 '//処理対象の行番号(2行目に設定)  s = st '//雛型の文字をコピー  For col = 1 To 9 '//A~I列までをループ(col=列番号)   stmp = "$" & Format(col, "#")    '//各セルの内容で置換え   s = Replace(s, stmp, sht.Cells(rw, col).Text, 1, -1, 1)  Next col  sht.Cells(rw, 14).Value = s '//結果をN列に入れる 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でのプログラミングを行っているので観点 の抜けなどが多分にあると思われます。 どんな小さなことでもご指摘頂けないでしょうか? 宜しくお願い致します。

  • マクロで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

  • エクセルのマクロについて

    下記は、A列3行の7文字目~10文字と B列5行~文字のある最後の行までの範囲の左から1文字目~4文字 に相違がある場合 MsgBox i & “行目” を出す。 というマクロなのですが、『B列5行~文字のある最後の行までの範囲』の中でも『空白のセルに関してはMsgBox不要』というふうに付加えたいのですがどのようにすればよいでしょうか。 Sub Macro1() Dim i As Long Dim sOrgText As String Dim ltotal As Long With ActiveSheet sOrgText = Mid(.Cells(3, 1), 7, 4) ltotal = .Cells(65536, 2).End(xlUp).Row For i = 5 To ltotal If Not Mid(.Cells(i, 2), 1, 4) = sOrgText Then MsgBox i & "行目" End If Next i End With End Sub