質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

1回答

2849閲覧

Accessで、32bitを64bitに変換したいです。

thth456

総合スコア1

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

0クリップ

投稿2022/10/01 05:44

前提

Accessで、32bitを64bitに変換したいのですが、
「型が一致しません」というエラーが起きてしまいます。

どうやら、GlobalSize()関数でエラーが起きているようです。
でも引数の型はLongPtrになっているので、なぜなのか分からず詰まっています。

ClipboardGetTextData = String$(GlobalSize(hGlobalMemory), vbNullChar) ' バッファ領域を確保する

ご教授いただければ幸いです。

Option Compare Database Option Explicit #If VBA7 Then ' 64-bit Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr Private Declare PtrSafe Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalFree Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalSize Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long Private Declare PtrSafe Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, ByVal lpString2 As Any) As LongPtr #End If '// '// GlobalAlloc wFlags パラメータ '// Private Const GMEM_MOVEABLE As Long = &H2 ' 移動可能メモリを割り当てます。メモリの断片化を防ぎます Private Const GMEM_ZEROINIT As Long = &H40 ' メモリの内容を 0 へ初期化します。 Private Const GHND As Long = (GMEM_MOVEABLE Or GMEM_ZEROINIT) ' 上記の各フラグの組み合わせです '// '// Get/SetClipboardData wFormat パラメータ '// Private Const CF_TEXT As Long = &H1 Public Function ClipboardGetTextData() As String Dim hClipMemory As LongPtr, hGlobalMemory As LongPtr If OpenClipboard(0) <> 0 Then hClipMemory = GetClipboardData(CF_TEXT) ' クリップボードオブジェクトのハンドルを取得します。 hGlobalMemory = GlobalLock(hClipMemory) ' クリップボードヘの先頭アドレスを取得します。 ClipboardGetTextData = String$(GlobalSize(hGlobalMemory), vbNullChar) ' バッファ領域を確保する Call lstrcpy(ClipboardGetTextData, hClipMemory) ' 確保したバッファヘ文字列をコピーします。 Call GlobalUnlock(hClipMemory) ' グローバルメモリオブジェクトのロックを解除します。 Call CloseClipboard ' クリップボードの権限を破棄します。 End If End Function Public Function ClipboardSetTextData(ByVal sTextData As String) As Boolean Dim hGlobalMemory As LongPtr, hClipMemory As LongPtr ' VBA では内部処理において文字列を Unicode で扱っているため、単純にバイト数を ' 取得すると半角・全角にかかわらず1文字2バイトが返ってきます。 ' そのため文字コードを Shift_JIS に変換後にバイト数を取得してます。 hGlobalMemory = GlobalAlloc(GHND, LenB(StrConv(sTextData, vbFromUnicode)) + 1) hClipMemory = GlobalLock(hGlobalMemory) ' 確保したバッファヘの先頭アドレスを取得します。 Call lstrcpy(hClipMemory, sTextData) ' 確保したバッファヘ文字列をコピーします。 Call GlobalUnlock(hGlobalMemory) ' グローバルメモリオブジェクトのロックを解除します。 If OpenClipboard(0) <> 0 Then ' クリップボードの内容の変更権限を取得します。 Call EmptyClipboard ' 現在のクリップボードを空にします。 ' クリップボードにデータを格納する。その際引数で渡されたグローバルメモリブロックは ' システムが管理するため、ハンドルの解放やロックし続けることをしてはなりません。 Call SetClipboardData(CF_TEXT, hGlobalMemory) Call CloseClipboard ' クリップボードの権限を破棄します。 ClipboardSetTextData = True Else ' クリップボードが他のプログラムなどで使用されている。 ' 使用されなかったハンドルを解放する Call GlobalFree(hGlobalMemory) ClipboardSetTextData = False End If End Function

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

String 関数 (Visual Basic for Applications) | Microsoft Learn

vba

1ClipboardGetTextData = String$(GlobalSize(hGlobalMemory), vbNullChar) ' バッファ領域を確保する

String関数の引数がLong型なので、それにLongPtr型を入れようとしているので、型が合わないとなるのでしょう。

vba

1ClipboardGetTextData = String$(CLng(GlobalSize(hGlobalMemory)), vbNullChar) ' バッファ領域を確保する

とすればエラーなく結果が返るようです。
ただ、クリップボードのサイズがLong型より多い場合はどうなるかは試してません。
たぶん、Long型のサイズに切り取られると思いますが。

おまけ

ちなみに、クリップボードからテキストを取得したり、送ったりするなら、 APIを使わず MSForms.DataObject を使う方法があります。こちらの方が簡単だと思います。

クリップボードとデータのやりとりをする:Excel VBA|即効テクニック|Excel VBAを学ぶならmoug

上記はExcelのVBAですが、Access VBAでも使えます。
上記を参考に、「Microsoft Forms 2.0 Object Library」に参照設定をします。

あとは、標準モジュールに下記のコードを記述します。

vba

1Public Function GetClipboardText() As String 2 On Error GoTo ErrExit 'クリップボードにテキストデータがない場合のエラー対策 3 With New MSForms.DataObject 4 .GetFromClipboard '変数のデータをDataObjectに格納する 5 GetClipboardText = .GetText 6 End With 7ErrExit: 8End Function 9 10Public Function SetClipboardText(ByVal sTextData As String) As Boolean 11 On Error GoTo ErrExit 'クリップボードにテキストデータがない場合のエラー対策 12 With New MSForms.DataObject 13 .SetText sTextData '変数の値をDataObjectに格納する 14 .PutInClipboard 'DataObjectのデータをクリップボードに格納する 15 SetClipboardText = True 16 End With 17ErrExit: 18End Function 19 20Public Sub Test() 21 Dim s As String 22 s = "Test" 23 24 If SetClipboardText(s) Then MsgBox "クリップボードにテキストを格納しました。" 25 26 MsgBox "クリップボードのテキストは'" & GetClipboardText() & "'" 27 28End Sub

投稿2022/10/01 06:19

編集2022/10/01 07:35
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thth456

2022/10/01 07:36

ご回答ありがとうございます。 自分でも調べたところ、確かにString関数の引数はLong型になっていました! おかげさまで無事、解決しました。
thth456

2022/10/01 07:37

おまけもありがとうございます。 試してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問