Excel VBAでのAPI呼び出しにおけるエラーの解決方法

このQ&Aのポイント
  • Excel VBAを使用してAPIのSetActiveWindowを呼び出そうとした際に、宣言のところでエラーが発生しました。設定方法に誤りがある可能性があります。
  • エラーメッセージによると、定数、固定長文字列、配列、ユーザ定義型、およびDeclareステートメントは、オブジェクトモジュールのパブリックメンバとしては使用できません。
  • ウィンドウをアクティブな状態にするためには、SetActiveWindowの宣言方法に問題があるかもしれません。正しい宣言方法を教えていただけると助かります。
回答を見る
  • ベストアンサー

Excel VBA でのAPI呼び出しが・・・

マクロ初級です。 windowsXP(SP3) office2007 Excelのマクロで、APIのSetActiveWindowを使おうとしましたが、宣言のところで エラーがでました。  設定は、  Public Declare Function SetActiveWindow Lib "user32" (ByVal hWnd As Long) As Long  もしくは  Public Declare Function SetActiveWindow Lib "user32" (ByVal hWnd&) As Long  コンパイルエラー  定数、固定長文字列、配列、ユーザ定義型および Declare ステートメントは  オブジェクトモジュールのパブリックメンバとしては使用できません。 ウィンドウをアクティブな状態等に用いたいのですが、定義の仕方が悪いのでしょうか? 皆さま、ご教授下さい。

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

  • ベストアンサー
  • ShowMeHow
  • ベストアンサー率28% (1424/5027)
回答No.1

標準モジュールを追加してそこに宣言してください。

その他の回答 (1)

  • DreamyCat
  • ベストアンサー率56% (295/524)
回答No.2

>>パブリックメンバとしては使用できません。<<     ↓  当該モジュールだけの範囲で使いたいなら Public ではなくPrivateで。

関連するQ&A

  • 64ビットエクセルでのAPI宣言/PtrSafe

    エクセルのInputboxで、入力された文字列を自動的にアスタリスクで隠すようにする方法を探し http://okwave.jp/qa/q2371878.html の回答No1のコードがまさに最適なコードで、これまで非常に助かっていました。 ところが、64bitのエクセルでは動かないことがわかりました。 表示されたエラーメッセージの言葉から調べて、PtrSafeという言葉を入れなければならないようなのでAPI宣言を以下のようにしてみました。 #If VBA7 And Win64 Then '64ビット版 Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _ (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long #Else '32ビット版 Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _ (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long #End If ところが、回答No1のコードで Sub Report_Open() を実行すると Public Function InputBoxDK(Prompt, Optional Title, Optional Default, Optional XPos, _ Optional YPos, Optional HelpFile, Optional Context) As String のところがハイライトされてエラーになります。 どう直せば良いのでしょうか? 全文のコードを乗せると字数制限に引っかかりますので、申し訳ありませんが宣言以外の部分は http://okwave.jp/qa/q2371878.html の回答No1のコードを見てくださいますようお願いします。

  • VBAでSetTextColorがうまくいかない

    EXCELのVBAでユーザーフォームを使ったグラフィック表示のプログラムを 作っているのですが、SetTextColorでテキスト色の設定をしようと してもうまくいきません。何故か設定しようとする色の値が無視されて 「1304008」が設定されてしまいます。(GetTextColorで確認) そしてそれ以降何を設定してもこの状態のままです。 何か考えられることがありますでしょうか。 下にそのプログラムを示します。 ちなみにSetBKColorやAngleArcなど他のグラフィック命令は問題なく 動いていてSetTextColorだけがうまくいってない状態です。 '------------------------------------------------- ' ユーザーフォーム用プログラム '------------------------------------------------- Private Declare Function GetActiveWindow Lib "user32" () As Long Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _ ByVal hwndParent As Long, _ ByVal hwndChildAfter As Long, _ ByVal lpszClass As String, _ ByVal lpszWindow As String) As Long Private Declare Function GetDC Lib "user32" ( _ ByVal hWnd As Long) As Long Private Declare Function ReleaseDC Lib "user32" ( _ ByVal hWnd As Long, _ ByVal hdc As Long) As Long Private Declare Function SetTextColor Lib "gdi32" _ (ByVal hdc As Long, crColor As Long) As Long Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" _ (ByVal hdc&, ByVal x&, _ ByVal y&, ByVal lpString$, ByVal nCount&) As Long Dim hWnd As Long Dim hdc As Long Public Sub UserForm_Activate() DoEvents hWnd = FindWindowEx(GetActiveWindow, 0, "F3 Server 60000000", "") hdc = GetDC(hWnd) ret = SetTextColor(hdc, RGB(255, 0, 0)) ret = TextOut(hdc, 0, 0, "abc", 3) Call ReleaseDC(hWnd, hdc) End Sub '-------------------------------------------------

  • VBA ウィンドウの列挙 Win32 API

    http://d.hatena.ne.jp/cartooh/20090618 上記のページに記載されているVBAです。 動作は確認できたのですが、どのような処理の流れとなっているのかがわかりません。 どなたかコメントを付けていただけないでしょうか。 よろしくお願いいたします。 Option Explicit Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal cnm As String, ByVal cap As String) As Long Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, _ ByVal cch As Long) As Long Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, _ ByVal lParam As Long) As Long Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long Const INDENT_KEY = "INDENT" Public Function EnumChildWindowsProc(ByVal hWnd As Long, ByVal lParam As Object) As Long EnumChildWindowsProc = EnumWindowsProc(hWnd, lParam) End Function Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Object) As Long EnumWindowsProc = True If IsWindowVisible(hWnd) = 0 Then Exit Function End If Dim strClassName As String ' * 255 Dim strCaption As String ' * 255 strClassName = String(255, vbNullChar) strCaption = String(255, vbNullChar) GetWindowText hWnd, strCaption, Len(strCaption) GetClassName hWnd, strClassName, Len(strClassName) strCaption = RTrim(left(strCaption, InStr(1, strCaption, vbNullChar) - 1)) strClassName = RTrim(left(strClassName, InStr(1, strClassName, vbNullChar) - 1)) ActiveCell.Cells(1, 1).Value = Hex(hWnd) ActiveCell.Cells(1, 2).Value = IsWindowVisible(hWnd) ActiveCell.Cells(1, 3).Value = strCaption ActiveCell.Cells(1, 4).Value = strClassName ActiveCell.Cells(2, 2).Activate Dim c As Collection Set c = lParam Dim indent As Long indent = c(INDENT_KEY) c.Add String(indent * 2, " ") & Hex(hWnd) & " " & strCaption & " " & strClassName, before:=c.Count indent = indent + 1 c.Remove INDENT_KEY c.Add indent, INDENT_KEY Call EnumChildWindows(hWnd, AddressOf EnumChildWindowsProc, ObjPtr(c)) indent = c(INDENT_KEY) - 1 c.Remove INDENT_KEY c.Add indent, INDENT_KEY ActiveCell.Cells(1, 0).Activate End Function Sub hoge() Application.ScreenUpdating = False Dim sht As Worksheet Set sht = ThisWorkbook.Worksheets(1) sht.UsedRange.Clear sht.Activate sht.Range("A1").Activate Dim c As Collection Set c = New Collection c.Add 0, INDENT_KEY Dim ret As Long ret = EnumWindows(AddressOf EnumWindowsProc, ObjPtr(c)) c.Remove INDENT_KEY Set sht = ThisWorkbook.Worksheets(2) sht.UsedRange.Clear sht.Activate sht.Range("A1").Activate Dim o As Variant For Each o In c ActiveCell.Value = o ActiveCell.Cells(2, 1).Activate Next Application.ScreenUpdating = True End Sub

  • EXCELVBA フォルダ検索API

    エクセルからVBAでフォルダを選択させるコマンドを、APIを使ってフォルダ検索ダイアログボックスを出すまでは見よう見真似でできるのですが、このとき「あたらしいフォルダ」のボタンは必要ないので出したくないのですが、どこかに定数を指定すればよろしいかご存知でしたら教えてください。 (使用OS: Windows2000,Excel:2003) ちなみにコピペした宣言部分は以下のものです。 *************** Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _ (ByVal pidl As Long, ByVal pszPath As String) As Long Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _ (lpBrowseInfo As BROWSEINFO) As Long Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long) Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Public Const WM_USER = &H400 Public Const BFFM_SETSELECTIONA = (WM_USER + 102) Public Const BFFM_INITIALIZED = 1 ********************

  • Excel VBA のコンパイルエラー

    Excel VBA で GDI32 にある API を declare するとメモリ不足のコンパイルエラー となってしまいます。 どなたか解決策を御教示下さい。 使用するAPI は GetTextExtentPoint32 です。 コンパイルエラーが起きるVBAコードは、MSのVBサンプルから拾ったものです。 private Declare Function GetTextExtentPoint32 Lib "gdi32" Alias "GetTextExtentPoint32A" ( _ ByVal hdc As Long, _ ByVal lpsz As String, _ ByVal cbString As Long, _ ByRef lpSize As CSize) As Long Private Type CSize cx As Long cy As Long End Type 同じ GDI32 にある DeleteObject の declare 文はエラーが発生しません。 環境は以下の通りです。 Excel 2007 OSはVista 32bit メモリは 3G で約60%使用 宜しくお願いします。

  • Excel VBAでアプリのウィンドウ名取得

    WindowsXP, Excel2007で、ExcelからIE8にキーコードを送りたいです。 ネットで拾った以下のコードにより、 Option Explicit Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Function activate_win(win_name As String) As Long Dim hwindow As Long hwindow = FindWindow(vbNullString, win_name) If hwindow <> 0 Then SetForegroundWindow hwindow activate_win = hwindow End Function Call activate_win("ウィンドウ名") Sendkeys "ABC", True のような形で、メモ帳での動作は確認したのですが、 IEだとウィンドウがアクティブになってくれません。 おそらくウィンドウタイトルを間違えているのだと思われますが、 全角半角などを変えてみたりしても、どう見比べてみても間違いがわかりません。 見た目ではわからない、似た文字だが違うということではないかと思っています。 そこで、開いているアプリのウィンドウ名すべてをメモ帳に書き出すような (あるいは任意のアプリにペーストできるようにするような)コードはないでしょうか? よろしくお願いします

  • VBA ユーザーフォームの×ボタン制御の不具合

    PowerPoint VBAで複数のユーザーフォームからなるVBAマクロを作成しました。 フォーム内の「次へ」「前へ」ボタンでのみ、マクロの実行制御をしているので、途中で右上の×を押されると、想定外エラーが発生します。 そこで、一番下に貼りつけたようなコードを全てのフォームに挿入することで、右上の×が表示されないようにしました。 あくまでフォームにしかコードは埋め込んでいません。 (標準モジュール、クラスには入ってません) ですが、極稀に、「フォームの右上×」ではなく、「PowerPointの右上×」が非表示になってしまう現象が発生します。 いろいろやるうちに再現はするのですが、厳密な再現手順がよくわかりません。 状況と下記ソースから、どこらへんに原因がありそうかアドバイス頂けないでしょうか? 全コードは出せない部分が多いのですが、アドバイスにあたり必要なコードがあれば、別途貼らせて頂きます。 Private Const GWL_STYLE = (-16) Private Const WS_SYSMENU = &H80000 ' ウィンドウに関する情報を返す Private Declare Function GetWindowLong Lib "USER32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long ' ウィンドウの属性を変更 Private Declare Function SetWindowLong Lib "USER32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long ' Activeなウィンドウのハンドルを取得 Private Declare Function GetActiveWindow Lib "USER32.dll" () As Long ' メニューバーを再描画 Private Declare Function DrawMenuBar Lib "USER32.dll" (ByVal hWnd As Long) As Long ' フォームアクティブ時処理 Private Sub UserForm_Activate() Dim hWnd As Long Dim Wnd_STYLE As Long hWnd = GetActiveWindow() Wnd_STYLE = GetWindowLong(hWnd, GWL_STYLE) Wnd_STYLE = Wnd_STYLE And (Not WS_SYSMENU) SetWindowLong hWnd, GWL_STYLE, Wnd_STYLE DrawMenuBar hWnd End Sub

  • 「コンパイルエラー End Subが必要です。」

    Access2016でファイルを作成しているのですが、下記のVBAを実行しようとすると、「コンパイルエラー End Subが必要です。」とエラーメッセージが返ってきてしまいます。 構文の修正が必要であるとお気づきであれば、その箇所を教えていただけないでしょうか。初歩的な質問で恥ずかしい限りですが、何卒よろしくお願い致します。 Option Compare Database Option Explicit Public Declare PtrSafe Function SetWindowPos Lib "user32" _ (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _ ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, _ ByVal fuFlags As Long) As Long Public Declare PtrSafe Function GetSystemMenu Lib "user32" _ (ByVal hWnd As Long, ByVal fRever As Long) As Long Public Declare PtrSafe Function RemoveMenu Lib "user32" _ (ByVal hMenu As Long, ByVal uItem As Long, ByVal fuFlags As Long) As Long Public Const SWP_NOMOVE = &H2 Public Const SWP_NOSIZE = &H1 Public Const HWND_TOP = &H0 Public Const SC_SIZE = &HF000 Public Const SC_MAXIMIZE = &HF030 Public Const SC_CLOSE = &HF060 Public Const SC_RESTORE = &HF120 Public Const MF_BYCOMMAND = &H0& Public Sub test() Private Sub Form_Open(Cancel As Integer) Dim hWnd As Long hWnd = Application.hWndAccessApp SetWindowPos hWnd, HWND_TOP, 0, 0, 800, 600, SWP_NOMOVE hWnd = GetSystemMenu(hWnd, 0) RemoveMenu hWnd, SC_SIZE, MF_BYCOMMAND End Sub

  • Excel2003VBAでクリップボードにあるビットマップの操作について

    Excel2003VBAにおいてクリップボードにあるビットマップの画像の任意の1pxの色を、 ペイントのスポイトツールのように取得するマクロを作成したいのですが GetPixelという関数で画像の任意1pxの色を取得できる所までは調べられたのですが、 それをクリップボードの画像で使用することができませんでした。 以下は、GetPixel関数を試してみた時のソースになります。 '------------------------------------------------------------------ Option Explicit Declare Function GetDesktopWindow Lib "user32" () As Long Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal Y As Long) As Long Sub ピクセル色獲得() Dim hwnd As Long Dim hdc As Long hwnd = GetDesktopWindow() hdc = GetWindowDC(hwnd) Debug.Print Hex(GetPixel(hdc, 100, 200)) End Sub '------------------------------------------------------------------ 上記ソースで任意1pxの色を取得できたため クリップボードの画像の色を取得するマクロを下記のように作成しました。 '--------------------------------------------------------------- Option Explicit Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal Y As Long) As Long Sub クリップボードピクセル色獲得() Dim CB As Variant Dim i As Long CB = Application.ClipboardFormats Debug.Print Hex(GetPixel(CB, 100, 200)) End Sub '--------------------------------------------------------------- 型が一致しません と言われ動きません。 以上です、よろしくお願いいたします。

  • VBAにおける Option Explicitの役割

    VBAにおける Option Explicitの役割 VBAでゲームを作ることを勉強している初心者です。 本に従ってもっとも基本的なスロットゲームをためしました。 プログラム本体の前にある下記のOption Explicitを省くとコンパイルエラーになります。 VBAにおける Option Explicitはプログラム本体中にあるどのキーがどのスロットを止めるなどの指示を 具体的記述なしに有効にするなどの役目があるのでしょうか。 Option Explicit Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Declare Function GetTickCount Lib "kernel32" () As Long 'Windows起動後経過時間取得API どなたか教えていただけると助かります。 よろしくお願いいたします。

専門家に質問してみよう