64bit 32Bit Access Excel VBA WinAPIを使用してフォームに最小化、最大化ボタンをつける 

#まずUserForm1を挿入して作ります
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/2eb2d290-0e99-080c-b5ab-286f0d773c80.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/06fe071f-19b0-ee09-73a7-a9c6c4790a84.png)

#VBAで64/32Bit Win32APIはDeclrareから先に記述する
Declare 、列挙、構造体（コンストラクタ）Type 、API用の定数 、Function/Sub
共用の場合は定数類から先に記述した方がいいようです。ただしPrivateにしないとエラーが出ます。
Declareで宣言するときに構造体をさすときにあらかじめないのも変ですし、たまにエラーが出ます。
順番はこうなります。これはVBAに目次兼備忘録として記述します。使わないものには<This Module is none.とかくと簡易な目次となります。
エラーにならない限り可能な限り各区画ごとにIf VBA7をかけて場合分けをします。

'1/5 Declrare Section For Win32API
'2/5 Enum Section For Win32API <This Module is none.
'3/5 Type Section For Win32API <This Module is none.
'4/5 Const Section For Win32API
'5/5 Function Section For Win32API <This Module is none.
'Global / Private / Dim Section For VBA
'Type Section For VBA
'Const Section For VBA


#コード

##UserForm Initializeに書く

```vb
Option Explicit
'Version2 Update 2018/8/17
'1/5 Declrare Section For Win32API
'2/5 Enum Section For Win32API <This Module is none.
'3/5 Type Section For Win32API <This Module is none.
'4/5 Const Section For Win32API
'5/5 Function Section For Win32API <This Module is none.
'Global / Private / Dim Section For VBA <This Module is none.
'Type Section For VBA <This Module is none.
'Const Section For VBA <This Module is none.

'1/5Declrare Section For Win32API
'ユーザーフォームに最小化ボタンをつけるためのDeclare
#If VBA7 And Win64 Then
Private Declare PtrSafe Function FindWindow _
Lib "USER32" Alias "FindWindowA" _
(ByVal lpClassName As String _
, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetActiveWindow Lib "USER32" () As LongPtr

#Else
Private Declare PtrSafe Function FindWindow _
Lib "USER32" Alias "FindWindowA" _
(ByVal lpClassName As String _
, ByVal lpWindowName As String) As Long
#End If
'GetWindow
#If VBA7 Then
#If Win64 Then
Private Declare PtrSafe Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
#Else
'Jkp-AdsのPrivateはExcel2013 32BitではDeclrareがモジュールの最上位でないと失敗するがPrivateだと成功しない LongPtr
'Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare Function GetWindowLongPtr _
Lib "USER32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long
#End If
#Else
'jkp-adsの
'Private Declare Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long はExcel2013 32bitでは失敗する
'GetWindowLongPtrでもGetWindowLongでも32Bitは問題にしない
Declare Function GetWindowLong _
Lib "USER32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long 'Declareが最上部でないときはPrivateでないと失敗する。記述時にエラーが起きてもSubプロシージャでコンパイルや実行の時エラーにならなければよい。
#End If

'SetWindowLong
#If VBA7 Then
'Excel 2007Later
#If Win64 Then
'Excel 2007 Later And 64-bit
Private Declare PtrSafe Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
'Excel 2007 Later And 32-bit
' Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr はDeclareがモジュールの最上位でないとエラーになる excel2013(32bit)は失敗する
Private Declare Sub SetWindowLongPtr _
Lib "USER32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long _
, ByVal dwNewLong As Long) 'PrivateではないとExcel2013 32bitでは失敗する Public不可
#End If
#Else
'Excel 2007 ealier
Private Declare Sub SetWindowLong _
Lib "USER32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long _
, ByVal dwNewLong As Long) 'PrivateではないとExcel2013 32bitでは失敗する Public不可 ここはLongがつかない
#End If
#If VBA7 Then
Private Declare PtrSafe Function DrawMenuBar Lib "USER32" (ByVal hWnd As LongPtr) As Long 'Excel2013 32bit ではDeclareの位置がモジュールの最上部でないとPublicでは宣言できない
#Else
Public Declare Function DrawMenuBar Lib "USER32" (ByVal hWnd As Long) As Long
#End If

'4/5 Const Section//////////////////////////////////////////////////
Private Const GWL_STYLE As Long = -16
Private Const WS_THICKFRAME As Long = &H40000 'ウィンドウ フレームのウィンドウのサイズを使用できるを作成します。
Private Const WS_MAXIMIZEBOX As Long = &H10000 '最大化ボタン
Private Const WS_MINIMIZEBOX As Long = &H20000 '最小化ボタン
Private Const LP_CLASSNAME = "ThunderDFrame" 'Excel 2000以降で作られたフォーム
'代表的なアプリケーションのクラス名
'Excel「XLMAIN」　Word「OpusApp」　PowerPoint「PP10FrameClass」　Access「OMain」
'Visual Basic Editor「wndclass_desked_gsk」　Internet Explorer「IEFrame」
'メモ帳「Notepad」　ペイント「MSPaintApp」　電卓「SciCalc」　ワードパッド「WordPadClass」
'http://excel.syogyoumujou.com/memorandum/get_hwnd.html


'ユーザーフォームに(最大化)最小化ボタンをつけるためのSubプロシージャ
Private Sub UserForm_Initialize()
'最小化 MinimizBottumのみ
'Const fWINDOWSTYLE As Long _
= WS_MAXIMIZEBOX
'If You Want Maximize buttom Use this >>
Const fWINDOWSTYLE As Long _
= WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX
'’’変数を場合分けしないとエラーになる
#If VBA7 Then
#If Win64 Then
Dim myHwnd As LongPtr
Dim myWindowLong As LongPtr
myHwnd = FindWindow("ThunderDFrame", Caption)
myWindowLong = GetWindowLongPtr(myHwnd, GWL_STYLE)
SetWindowLongPtr myHwnd, GWL_STYLE, myWindowLong Or fWINDOWSTYLE
#Else
Dim myHwnd As Long
Dim myWindowLong As Long
myHwnd = FindWindow("ThunderDFrame", Caption)
myWindowLong = GetWindowLongPtr(myHwnd, GWL_STYLE)
SetWindowLongPtr myHwnd, GWL_STYLE, myWindowLong Or fWINDOWSTYLE
#End If
#Else
Dim myHwnd As Long
Dim myWindowLong As Long
myHwnd = FindWindow("ThunderDFrame", Caption)
myWindowLong = GetWindowLong(myHwnd, GWL_STYLE)
SetWindowLong myHwnd, GWL_STYLE, myWindowLong Or fWINDOWSTYLE
#End If
DrawMenuBar myHwnd
End Sub

```

## うまく動くとこんな感じになります
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/c5299646-5cc5-51fb-959b-700f6338b6b8.png)
最小、最大が可能になりました。

## Excel2013 32bitで動作確認したコードも上げます。
ただし上のバージョンアップ版で動きます。

```vb
Option Explicit
'1/5 Enum Section For Win32API <This Module is none.
'2/5 Type Section For Win32API <This Module is none.
'3/5 Const Section For Win32API
'4/5 Declrare Section For Win32API
'5/5 Function Section For Win32API <This Module is none.
'Dim Section For VBA <This Module is none.
'Type Section For VBA <This Module is none.
'Const Section For VBA <This Module is none.

'3/5 Const Section
Private Const GWL_STYLE As Long = -16
Private Const WS_THICKFRAME As Long = &H40000 'ウィンドウ フレームのウィンドウのサイズを使用できるを作成します。
Private Const WS_MAXIMIZEBOX As Long = &H10000 '最大化ボタン
Private Const WS_MINIMIZEBOX As Long = &H20000 '最小化ボタン
Private Const LP_CLASSNAME = "ThunderDFrame"
'4/5Declrare Section For Win32API
'ユーザーフォームに最小化ボタンをつけるためのDeclare
#If VBA7 And Win64 Then
Private Declare PtrSafe Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String _
, ByVal lpWindowName As String) As LongPtr
Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String _
, ByVal lpWindowName As String) As Long
#End If
'GetWindow
#If VBA7 Then
#If Win64 Then
Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
#Else
'Jkp-AdsのPrivate Declare PtrSafe Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtrはExcel2013 32Bitでは失敗する
Private Declare Function GetWindowLong _
Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long

#End If
#Else
'jkp-adsのPrivate Declare Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long はExcel2013 32bitでは失敗する
Private Declare Function GetWindowLong _
Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long

#End If
'SetWindowLong
#If VBA7 Then
#If Win64 Then
Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
' Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr はエラーになる excel2013(32bit)は失敗する
Private Declare Sub SetWindowLong _
Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long _
, ByVal dwNewLong As Long) 'PrivateではないとExcel2013 32bitでは失敗する Public不可
#End If
#Else
'jkp-adsの 'Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long は失敗する
Private Declare Sub SetWindowLong _
Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long _
, ByVal dwNewLong As Long) 'Excel2013 32bitではPublic可能
#End If

#If VBA7 Then
Private Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hWnd As LongPtr) As Long 'Excel2013 32bit ではPublicでは宣言できない
#Else
Public Declare Function DrawMenuBar Lib "user32" (ByVal hWnd As Long) As Long
#End If
'ユーザーフォームに(最大化)最小化ボタンをつけるためのSubプロシージャ
'WS_THICKFRAME はフォームの大きさを可変することができるため付け加えている。

Private Sub UserForm_Initialize()
'最小化 MinimizBottumのみ
'Const fWINDOWSTYLE As Long _
= WS_MAXIMIZEBOX
'If You Want Maximize buttom Use this >>
Const fWINDOWSTYLE As Long _
= WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX
#If Win64 Then
Dim myHwnd As LongPtr
Dim myWindowLong As LongPtr
#Else
Dim myHwnd As Long
Dim myWindowLong As Long
#End If
myHwnd = FindWindow("ThunderDFrame", Caption)
myWindowLong = GetWindowLong(myHwnd, GWL_STYLE)
SetWindowLong myHwnd, GWL_STYLE, myWindowLong Or fWINDOWSTYLE
DrawMenuBar myHwnd
End Sub
```
64/32共用化の場合Privateをつけていないとエラーになる可能性が高い。
また、jkp-adsのコードは32bitもLongPtrにしているが、エラーになる。
これはTypeから書いているからかもしれない

#● 補足 ●

##Sub とFunctionの違い
戻り値を必要としない場合には、Subプロシージャとして宣言してもかまいません。

```vb

Declare Sub GetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT)

Declare Sub SetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT)
```

##VBA7 とWin6
[VBAをEXCEL2007, 2010, 2013の32/64 bitの全てに対応させるにはどうすれば良いのか？解決！](https://blog.goo.ne.jp/mumbai/e/dc90cf94fc40baebf807f1913de4fc10)
>インターネットで調べると、この件に関してはいろんな情報がヒットするが、やはりマイクロソフトの公式情報を確認するのが間違いないだろう。
 
>    Office 2010 の 32 ビット バージョンと 64 ビット バージョンとの互換性
    https://msdn.microsoft.com/ja-jp/library/office/ee691831?f=255&MSPPError=-2147217396
 
>この情報によると、
 
>    EXCEL2007は32bit版のみ
    EXCEL2010から32bit版, 64bit版の二種類になった
    EXCEL2010以降では、VBA7 と Win64 という 2 つの条件付きコンパイル定数が用意されている。
 
>である。
>つまり、VBA7という定数を使うとEXCELのバージョンが2007以前か2010以降かが区別できる。
一方、Win64は、実行しているEXCELのバージョンが64か32かの区別が出来る。Win64という名前から、Windowsのビット数を表していると錯覚しがちだが、
あくまで実行しているEXCELのビット数なので注意。
従って、Windows7やWindows8の64bit版でEXCEL2010(32)を実行していると Win64は定義されない。

これだけ見てもなんのことだかわかりません。これは重要なポイントを見つけました。
###VBA7をWin64で知られていないこと
実は\#IF VBA7はDeclareだけ使うのではありません。
TypeでもDimでも、はてまたSubプロシージャでも使えます。
節操がありません。
なぜ必要なのでしょうか。?
###VBA7で分けられるのはLongPtr
VBA7であるかないかで最もわかりやすいものがLongPtrです。VBA7であれば64/32を問わずLongPtrが使えます。というかそのためのものです。
つまりDeclareで返り値がLongPtrであればTypeやDimもLongPtrにしなければなりません。
このためどこでも場合分けで切るようです。
LongPtrがVBA7以降において64/32両方使えるということになりました。
ところが、よくよくDeclareをみるとLongではなく末尾がLongPtrになっているものがあります。
これは純粋な32Bitでは使えません。
これが最大の違いです

>なので、ほとんどの場合、VBA7を使って
VBA7 suffices in almost all cases. In case there is an exception it is mentioned in the sample code above.


```vb

#If VBA7 then
Declare PtrSafe　　SetWindowLongPtrA　LongPtr
#Else
Declare SetWindowLongA　Long
#End If
```
のようになるこうしきのこれ https://docs.microsoft.com/ja-jp/office/vba/Language/Concepts/Getting-Started/compiler-constants ではさらに
このように記述している。

```vb
#If Win64 Then 
' Win64=true, Win32=true, Win16= false 
#ElseIf Win32 Then 
' Win32=true, Win16=false 
#Else 
' Win16=true 
#End If
```
####さらにMACもある
```vb
#If Mac Then
#Else
#End If
```
実はこれでMacかどうかも区別できる。

### Win64で分けられるのはPtrSafeが付くかつかないか
ごく少数のものであるが、重要なAPIにPtrSafeが付かないものがある。今回もある。

```vb
'SetWindowLong
#If VBA7 Then
'Excel 2007Later
#If Win64 Then
'Excel 2007 Later And 64-bit
Private Declare PtrSafe Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
'Excel 2007 Later And 32-bit
'PTrSafeがつかない
' Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr はDeclareがモジュールの最上位でないとエラーになる excel2013(32bit)は失敗する
Private Declare Sub SetWindowLongPtr _
Lib "USER32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long _
, ByVal dwNewLong As Long) 'PrivateではないとExcel2013 32bitでは失敗する Public不可
#End If
#Else
'Excel 2007 ealier
Private Declare Sub SetWindowLong _
Lib "USER32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long _
, ByVal dwNewLong As Long) 'PrivateではないとExcel2013 32bitでは失敗する Public不可 ここはLongがつかない
#End If
```

##癇癪をおこしたらPrivateにする
上記のコードのPrivate Sub UserForm_Initialize()くらいでALT-D-L
でコンパイルするとたまにエラーになる。するとPublic DeclareをPrivateにするとうまくいく。
しかもPublicでも動く時があり、まったく気まぐれで、どういうことか不明である。

##広く共用にはほどとおい
実際に64bitと32bitでコードを動かすと非常に不安定で、たとえば会社内でコードを共有するレベルなら安定するが、広く公開してもエラーになる可能性がある。もし動かないときは
 1. コンパイルしてPrivateをつける
 2. 変数がLongPtrかLongかみ分けてきちんと設定する
 3. それでもだめなら使わないコードは無効か、削除する
 4. それでもだめなら別の方法を使う

というように、共有にこだわるより安定運用に気を付けた方がよい。

#参考、参照サイト
'ClipBoard
' https://www.saka-en.com/office/vba-get-clipboard-api-64bit-excel/
####Windows 32 API Sample
' http://nonsoft.la.coocan.jp/Win32Api/index.html
Win32版のAPIを網羅している。
####Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support
[Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support ](https://www.microsoft.com/en-us/download/details.aspx?id=9970)
exe形式のファイルをダウンロードする。
 Instructions for use:
    After you installed this download, view the files as you normally would. By default, files are installed to the following location: C:\Office 2010 Developer Resources\Documents\.
CドライブのOffice2010Debelopper...というフォルダを作って展開する。だからと言ってOffice2010を持っていなくてもよい。Exe形式のファイルを実行するとこのフォルダが作成される。
この中のテキストファイルが64bit宣言なので、原則このままコピーする。しかし60000行以上あるので、全部一度にVBAのプロシージャに入れることはできない。


    Remove of this download:
    There is no removal feature for this download. 
'起動したアプリケーションの表示位置、サイズを指定する ACCESS
' https://www.moug.net/tech/acvba/0010014.html
' How to add minimize button for a userform?
' https://stackoverflow.com/questions/6567259/how-to-add-minimize-button-for-a-userform
####[jkp-ads](https://www.jkp-ads.com/articles/apideclarations.asp)
64bit-32bitのコード
ただし変数の定義もあるので注意すること。DeclaregaLongPtrなのにLongにするとエラーになる。
Functionも関数名がPtrがついたりする。単純にコピペするだけではなく、何が違うのかを確認して貼り付けた方がよい。うまく動かないときはPrivate Declareにする
' 

'[Declare ステートメント]( https://msdn.microsoft.com/ja-jp/vba/language-reference-vba/articles/declare-statement)
メモPtrSafe キーワード付きの Declare ステートメントが推奨構文です。 PtrSafe が含まれる Declare ステートメントが 32 ビットおよび 64 ビット プラットフォームの VBA7 開発環境で正常に機能するのは、64 ビット数を格納する必要がある Declare ステートメント内のすべてのデータ型 (パラメーターおよび戻り値) が 64 ビット整数用の LongLong またはポインターおよびハンドル用の LongPtr を使用するように更新されている場合のみです。VBA 6 以前のバージョンとの下位互換性を確保するには、以下の構文を使用します。

```vb
#If Vba7 Then
Declare PtrSafe Sub...
#Else
Declare Sub...
#EndIf
```

構文 1 (Sub)
[ Public |Private ] DeclarePtrSafe ** Sub** nameLib"libname" [ Alias"aliasname" ] [ ( [ arglist ] ) ]

構文 2 (Function)
[ Public |Private ] DeclarePtrSafeFunctionnameLib"libname" [ Alias"aliasname" ] [ ( [ arglist ] ) ] [ Astype ]

|指定項目|説明|
|:---:|:-----|
|Public オプション|すべての モジュール内の他のすべてのプロシージャで使用可能なプロシージャを宣言するために使用します。 |
|Private オプション| 宣言が実行されたモジュール内でのみ使用可能なプロシージャを宣言するために使用します。 |
|PtrSafe | 64 ビットでは必ず指定する必要があります。 PtrSafe キーワードは、 Declare ステートメントが 64 ビット バージョンの Microsoft Office で安全に実行されることを宣言します。 |
|Sub オプション ( Sub または Function を含める必要があります)。|プロシージャが値を返さないことを示します。 |
|Function オプション ( Sub または Function を含める必要があります)。|プロシージャが、 式で使用できる値を返すことを示します。 |
|name 必ず指定します|任意の有効なプロシージャ名です。DLL エントリ ポイントは大文字と小文字を区別します。 |
|Lib 必須||宣言するプロシージャが DLL またはコード リソースに含まれていることを示します。 Lib 句はすべての宣言で必要とされます。 |
|libname 必ず指定します|宣言するプロシージャが含まれる DLL またはコード リソースの名前です。 |
|Alias オプション|呼び出されるプロシージャが DLL 内で別の名前を持つことを示します。これは、外部プロシージャの名前がキーワードと同じ場合に役立ちます。また、DLL プロシージャの名前が、同じスコープ内のパブリック変数、定数、またはその他のプロシージャと同じ場合にも Alias を使用できます。さらに、DLL プロシージャ名の何らかの文字が DLL の名前付け規則によって許可されない場合にも Alias が便利です。 |
|aliasname オプション|DLL またはコード リソース内のプロシージャの名前です。1 番目の文字が番号記号 ( # ) でない場合、 aliasname は、DLL 内のプロシージャのエントリ ポイント名になります。1 番目の文字が ( # ) の場合、それに続くすべての文字がプロシージャのエントリ ポイントの序数を示す必要があります。 |
|arglist オプション|プロシージャが呼び出されるときにプロシージャに渡される 引数を表す変数のリストです。 |
|type オプション。|Function プロシージャによって返される値の データ型です。バイト型 ( Byte)、ブール型 ( Boolean)、整数型 ( Integer)、長整数型 ( Long)、 LongLong、 LongPtr、通貨型 ( Currency)、単精度浮動小数点型 ( Single)、倍精度浮動小数点型 ( Double)、10 進型 ( Decimal) (現在サポートされていません)、日付型 ( Date)、文字列型 ( String) (可変長のみ)、バリアント型 ( Variant)、 ユーザー定義型、または オブジェクト型 を指定できます ( LongLong は、64 ビット プラットフォームでのみ有効な宣言型です)。 |

arglist 引数の構文と指定項目は以下のとおりです。
[ Optional ] [ ByVal |ByRef ] [ ParamArray ] varname [ ( ) ] [ Astype ]


|指定項目|説明|
|:---:|:-----|
|Optional オプション。引数が必須でないことを示します。使用されている場合、 arglist 内の以降の引数すべてもオプションで、 Optional キーワードを使用して宣言する必要があります。 ParamArray が使用されている場合は、どの引数にも Optional を使用することはできません。 |
|ByVal |オプション。引数が 値によって渡されることを示します。 |
|ByRef |引数が 参照によって渡されることを示します。Visual Basic では、 ByRef が既定で設定されています。 |
|ParamArray オプション| arglist の最後の引数としてのみ使用され、最後の引数がバリアント型 ( Variant ) 要素の Optional配列であることを示します。 ParamArray キーワードを使用すると、任意の数の引数を提供できます。 ParamArray キーワードを ByVal 、 ByRef 、または Optional と共に使用することはできません。 |
|varname 必ず指定します|プロシージャに渡される引数を表す変数の名前です。この名前は変数の標準の名前付け規則に従っています。 |
|( )| 配列変数で必ず指定します。 varname が配列であることを示します。 |
|type オプション。|プロシージャに渡される引数のデータ型です。バイト型 ( Byte )、ブール型 ( Boolean )、整数型 ( Integer )、長整数型 ( Long )、 LongLong 、 LongPtr 、通貨型 ( Currency )、単精度浮動小数点型 ( Single )、倍精度浮動小数点型 ( Double )、10 進型 ( Decimal ) (現在サポートされていません)、日付型 ( Date )、文字列型 ( String ) (可変長のみ)、オブジェクト型 ( Object )、バリアント型 ( Variant )、ユーザー定義型、またはオブジェクト型 を指定できます ( LongLong は、64 ビット プラットフォームでのみ有効な宣言型です)。 |

解説
Function プロシージャでは、プロシージャのデータ型によって、プロシージャが返すデータ型が決まります。 arglist の後で As 句を使用すると、関数の戻り値の型を指定できます。 arglist 内で As 句を使用すると、プロシージャに渡す任意の引数のデータ型を指定できます。任意の標準データ型を指定するのに加えて、 arglist 内で As Any を指定すると、型チェックを禁止してあらゆるデータ型をプロシージャに渡すことができます。
空のかっこは、 Sub または Function プロシージャに引数がないことを示すと共に、何も渡されていないことが Visual Basic で確認される必要があることを示します。以下の例では、 First は引数を取りません。呼び出しで引数を使用する場合、引数を取りません。 First への呼び出しで引数を使用すると、エラーが発生します。
Declare Sub First Lib "MyLib" ()
引数リストを含める場合、プロシージャが呼び出されるたびに引数の数と型がチェックされます。以下の例では、1 つの長整数型 ( Long ) の引数を取ります。
Declare Sub First Lib "MyLib" (X As Long)

メモDeclare ステートメントの引数リストに固定長の文字列を含めることはできません。可変長の文字列のみをプロシージャに渡すことができます。固定長の文字列はプロシージャの引数として存在できますが、その文字列は、渡される前に可変長の文字列に変換されます。
メモ 外部プロシージャで値 0 の文字列が必要とされる場合、外部プロシージャを呼び出すときに vbNullString 定数を使用します。これは長さ 0 の文字列 ("") とは異なります。

```vb

' In Microsoft Windows (16-bit):
Declare Sub MessageBeep Lib "User" (ByVal N As Integer)
' Assume SomeBeep is an alias for the procedure name.
Declare Sub MessageBeep Lib "User" Alias "SomeBeep"(ByVal N As Integer)
' Use an ordinal in the Alias clause to call GetWinFlags.
Declare Function GetWinFlags Lib "Kernel" Alias "#132"()As Long

' In 32-bit Microsoft Windows systems, specify the library USER32.DLL,
' rather than USER.DLL. You can use conditional compilation to write
' code that can run on either Win32 or Win16.
#If Win32 Then
Declare Sub MessageBeep Lib "User32" (ByVal N As Long)
#Else
Declare Sub MessageBeep Lib "User" (ByVal N As Integer)
#End If


' 64-bit Declare statement example:
Declare PtrSafe Function GetActiveWindow Lib "User32" () As LongPtr

' Conditional Compilation Example
#If Vba7 Then
' Code is running in 32-bit or 64-bit VBA7.
#If Win64 Then
' Code is running in 64-bit VBA7.
#Else
' Code is not running in 64-bit VBA7.
#End If
#Else
' Code is NOT running in 32-bit or 64-bit VBA7.
#End If
```