[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『文字列クリップボード格納で文字化け』(ウルトラの孫)
文字列をクリップボードに格納するコードを作成中です。 下記のコードは簡単なテスト用です。 文字列をクリップボードに格納するFunctionを二通り テストしています。 cbsetBの方はtestのcbstrA、cbstrB両方ともきちん と格納できます。 しかし、cbsetAの方はtestのcbstrBはきちんと格納 できますが、cbstrAの方は文字化けしたものがクリップ ボードに格納されてしまいます。
CreateObject("Wscript.Shell").Exec("clip").StdIn.Write〜 は、何かしらの制約があるのでしょうか? ネット検索しても制約があるような記述は見つけられませんでした。
文字数に制約があるのかな、と思い、文字を削ったりしましたが、 文字数より文字列の内容か文字の組み合わせによるような気も します。 何かお気づきの方、ご教示お願いします。
Sub test() Dim cbstr As String cbstrA = "1234(定期点検用点検整備記録簿)" 'cbstrB = "1234(定期点検用点検整備記録)" Call cbsetA(cbstrA) 'Call cbsetB(cbstrA) End Sub
Function cbsetA(ByVal cbstr As String) CreateObject("Wscript.Shell").Exec("clip").StdIn.Write (cbstr) End Function
Function cbsetB(ByVal cbstr As String) Dim doA As MSForms.DataObject Set doA = New MSForms.DataObject doA.Clear doA.SetText Text:=cbstr doA.PutInClipboard End Function
< 使用 Excel:Excel2007、使用 OS:Windows10 >
CreateObject("Wscript.Shell").Exec("clip").StdIn.Write cbstr & vbLf とか CreateObject("Wscript.Shell").Exec("clip").StdIn.WriteLine cbstr とか CreateObject("Wscript.Shell").Exec "cmd.exe /c echo " & cbstr & " |clip" とか でうまくいくみたいです (´・ω・`) 2023/06/21(水) 14:23:46
こうするとウインドウが表示されないので、個人的にはこっちが好きかも
Sub test() Dim cbstrA As String cbstrA = "1234(定期点検用点検整備記録簿)" cbsetA cbstrA End Sub
Sub cbsetA(ByVal cbstr As String) CreateObject("Wscript.Shell").Run "cmd.exe /c echo " & cbstr & " |clip", 0, True End Sub (´・ω・`) 2023/06/21(水) 14:54:12
(´・ω・`)さん、ご教示ありがとうございます。
>CreateObject("Wscript.Shell").Exec("clip").StdIn.Write cbstr & vbLf >CreateObject("Wscript.Shell").Exec "cmd.exe /c echo " & cbstr & " |clip"
この二つは文字化けしませんでしたが、最後尾に改行が付いてしまいます。
>CreateObject("Wscript.Shell").Exec("clip").StdIn.WriteLine cbstr
このコードは、文字化けしてしまいました。
文字列をクリップボードに格納する方法はたくさんあるので目的としては解決している のですが、出来たら原因を究明したいと思います。
回避方法が内容でしたら使用を諦めます。 (ウルトラの孫) 2023/06/21(水) 15:56:55
CreateObject("Wscript.Shell").Exec("clip").StdIn.Write cbstr & vbLf は CreateObject("Wscript.Shell").Exec("clip").StdIn.Write cbstr & vbCrLf じゃないとダメみたい 文字のバイト区切りがうまくとれてないみたいなので、 文字列の終端を示すコードを入れてやればいいと思うのですが、 なにがいいのでしょうね? (´・ω・`) 2023/06/21(水) 16:16:12
vbNullCharでイケませんかね? (白茶) 2023/06/21(水) 16:28:19
>vbNullChar だめでした。ASCIIコード表のそれっぽいのはほとんど試しましたがダメでした
コマンドラインでClipコマンドにファイルを食わせてみたら、 改行コード(CRLF)がないと文字数によって化けるので、 Clipコマンド自体の仕様のような気がします。 (´・ω・`) 2023/06/21(水) 16:40:16
あー、ダメでしたか... ^^;
(白茶) 2023/06/21(水) 16:42:28
>コマンドラインでClipコマンドにファイルを食わせてみたら、 >改行コード(CRLF)がないと文字数によって化けるので、
コマンドライン上の話ですが、コードページをUnicode(UTF-8)にして(CHCP 65001)、 Unicodeのファイルを標準入力から食わせてやると改行コードがなくても大丈夫でした(たぶん)
Wscript.Shell をコードページをUnicodeにして起動して、 文字列を StrConv(cbstr,vbUnicode)して送り込めばいいんじゃないかと思いつつ、
>Wscript.Shell をコードページをUnicodeにして起動 どうしたら???? (´・ω・`) 2023/06/21(水) 17:05:15
わたしはあきらめました 別案は最初からでてますし というわけで撤退します
clipコマンドよりpowershellのset-clipboardのほうが良さげなんですが なんかこれはこれで、、、 (´・ω・`) 2023/06/21(水) 18:06:20
(´・ω・`)さん、白茶さん、いろいろご検討ありがとうございます。
スキャナから自動で現在日時のファイル名が付されて吐き出されたPDFファイルを手動で開いて中身を確認して 車のナンバー+(車検/自動車検査証記録事項/定期点検用点検整備記録簿/2年定期点検用点検整備記録簿/自賠) でリネームする作業をある程度自動化するツールを作り始めました。 TextBoxに車番、ListBoxで車検等を選択して文字列を結合したものをクリップボードに格納して、F2キーでファイル名を 選択状態にしてファイル名のところにCtrl+Vでクリップボードの内容を貼り付ける、というものです。 作成途中で文字化けに気が付きご相談した、というわけです。 ユーザーフォームを使ってますので参照設定を手動でしなくてもcbsetBが使えますので面倒はないのですが、クリップボード 格納の方法をいくつか試した中で文字化けが起きた、という具合です。
まだ作成途中ですが、ListViewにファイルをドラッグ&ドロップしてFileSystemObjectを使用してリネーム、という方向へ 方針転換しました。
お騒がせした挙句全然違う方法で申し訳ありませんが、質問事項の方法での解決は諦めました。 ご教示いただきありがとうございました。 (ウルトラの孫) 2023/06/21(水) 19:00:07
クリップボード関係だとAPI使ったやり方も候補のひとつではありましょう。 これも割と王道的手法だと思ってます。(個人的には ^^;)
Option Explicit 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 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 GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As LongPtr) Private Const GMEM_MOVEABLE As Long = &H2 Private Const GMEM_ZEROINIT As Long = &H40 Private Const GHND As Long = (GMEM_MOVEABLE Or GMEM_ZEROINIT) Private Const CF_UNICODETEXT As Long = &HD Sub SetClipboard(str As String) Dim h As LongPtr, p As LongPtr If OpenClipboard(0) <> 0 Then If EmptyClipboard() <> 0 Then h = GlobalAlloc(GHND, LenB(str) + 2&) p = GlobalLock(h) CopyMemory ByVal p, ByVal StrPtr(str), LenB(str) Call GlobalUnlock(h) Call SetClipboardData(CF_UNICODETEXT, h) Call CloseClipboard End If End If End Sub
Sub Test() SetClipboard "1234(定期点検用点検整備記録簿) / 56" & ChrW(8467) & " 78" & ChrW(13137) End Sub
(参考文献) 64bit VBAでクリップボードに文字列を設定・取得 - Qiita https://qiita.com/7shi/items/61f4c4e132835b26b3ea
(白茶) 2023/06/21(水) 19:05:01
白茶さん、追加回答ありがとうございます。
32bit版を試したらうまくいきました。 ありがとうございました。
また、↓も試してみました。こちらは一時的にコントロールを追加してますのであまり 使いたくはないですが・・・。
クリップボード格納の方法はいろいろありますのでいろいろ試してみたいと思います。 ありがとうございました。
'★参照設定 'Microsoft ActiveX Data Object
Sub test2() Dim mytb As OLEObject Dim ws As Worksheet Dim cbstr As String cbstr = "1234(定期点検用点検整備記録簿)" Set ws = ActiveSheet Set mytb = ws.OLEObjects.Add(ClassType:="Forms.TextBox.1", Link:=False, _ DisplayAsIcon:=False, Left:=0, Top:=0, Width:=1, Height:=1) With ws.OLEObjects(mytb.Name).Object .MultiLine = True .Value = cbstr .selstart = 0 .SelLength = Len(.Value) .Copy End With mytb.Delete Set mytb = Nothing Set ws = Nothing End Sub (ウルトラの孫) 2023/06/21(水) 19:29:09
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.