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

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

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

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

2444閲覧

[ Excel VBA for mac 16.35 ] 文字列をURIエンコードできません...

ucndev

総合スコア14

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/03/30 09:04

編集2020/03/30 09:05

環境

  • mac OS 10.15.4
  • Excel for mac 16.35(20030802)

実現したいこと

文字列をURIエンコードしたいです。

試したこと

1. JavaScript#encodeURI()を使う

vb

1 2Function UrlEncode(mySource As Variant) As String 3 Dim objSC As Object 4 Set objSC = CreateObject("ScriptControl") 5 objSC.Language = "JScript" 6 UrlEncode = objSC.CodeObject.encodeURIComponent(mySource) 7 Set objSC = Nothing 8End Function 9 10Sub test 11 MsgBox UrlEncode("テスト") 12End

** 結果 **
「ActiveXコンポーネントはオブジェクトを作成できません。」
とエラーが出ます。


2. rubyを使う

vb

1Private Declare PtrSafe Function popen Lib "libc.dylib" (ByVal command As String, ByVal mode As String) As LongPtr 2Private Declare PtrSafe Function pclose Lib "libc.dylib" (ByVal file As LongPtr) As Long 3Private Declare PtrSafe Function fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As LongPtr, ByVal items As LongPtr, ByVal stream As LongPtr) As Long 4Private Declare PtrSafe Function feof Lib "libc.dylib" (ByVal file As LongPtr) As LongPtr 5 6Function execShell(command As String, Optional ByRef exitCode As Long) As String 7 Dim file As LongPtr 8 file = popen(command, "r") 9 10 If file = 0 Then 11 Exit Function 12 End If 13 14 While feof(file) = 0 15 Dim chunk As String 16 Dim read As Long 17 chunk = Space(50) 18 read = fread(chunk, 1, Len(chunk) - 1, file) 19 If read > 0 Then 20 chunk = Left$(chunk, read) 21 execShell = execShell & chunk 22 End If 23 Wend 24 25 exitCode = pclose(file) 26End Function 27 28Function UrlEncode(mySource As Variant) As String 29 Dim command As String 30 Dim result As String 31 32 command = "do shell script ""ruby -r cgi -e 'puts CGI.escape(""" & mySource & """);'""" 33 result = execShell(command, exitCode) 34 UrlEncode = result 35End Function 36 37Sub test 38 MsgBox UrlEncode("テスト") 39End

** 結果 **
何もリターンされません。(空文字が返ります)
ターミナルでruby -r cgi -e 'puts CGI.escape("テスト");'を実行すると「%E3%83%86%E3%82%B9%E3%83%88」と返ります。


3. nkfを使う

vb

1 2Private Declare PtrSafe Function popen Lib "libc.dylib" (ByVal command As String, ByVal mode As String) As LongPtr 3Private Declare PtrSafe Function pclose Lib "libc.dylib" (ByVal file As LongPtr) As Long 4Private Declare PtrSafe Function fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As LongPtr, ByVal items As LongPtr, ByVal stream As LongPtr) As Long 5Private Declare PtrSafe Function feof Lib "libc.dylib" (ByVal file As LongPtr) As LongPtr 6 7Function execShell(command As String, Optional ByRef exitCode As Long) As String 8 Dim file As LongPtr 9 file = popen(command, "r") 10 11 If file = 0 Then 12 Exit Function 13 End If 14 15 While feof(file) = 0 16 Dim chunk As String 17 Dim read As Long 18 chunk = Space(50) 19 read = fread(chunk, 1, Len(chunk) - 1, file) 20 If read > 0 Then 21 chunk = Left$(chunk, read) 22 execShell = execShell & chunk 23 End If 24 Wend 25 26 exitCode = pclose(file) 27End Function 28 29Function UrlEncode(mySource As Variant) As String 30 Dim command As String 31 Dim result As String 32 33 command = "do shell script ""echo '" & mySource & "' | nkf -WwMQ | sed 's/=$//g' | tr = % | tr -d '\n'""" 34 result = execShell(command, exitCode) 35 UrlEncode = result 36End Function 37 38Sub test 39 MsgBox UrlEncode("テスト") 40End

** 結果 **
何もリターンされません。(空文字が返ります)
ターミナルでecho 'テスト' | nkf -WwMQ | sed 's/=$//g' | tr = % | tr -d '\n'を実行すると「%E3%83%86%E3%82%B9%E3%83%88」と返ります。


4. AppleScript経由でruby / nkfを使う

vb

1Function UrlEncode(mySource As Variant) As String 2 Dim result As String 3 4 result = AppleScriptTask("urlencode.applescript", "urlEncode", mySource) 5 UrlEncode = result 6End Function 7 8Sub test 9 MsgBox UrlEncode("テスト") 10End

applescript

1# ~/Library/Application Scripts/com.microsoft.Excel/urlencode.applescript 2on urlEncode(inData) 3 set scpt to "ruby -r cgi -e 'puts CGI.escape(""" & quote & inData & quote & """);'" 4 return (do shell script scpt) as string 5end urlEncode

** 結果 **
「プロシージャの呼び出し、または引数が無効です。」
とエラーが出ます。
(上はrubyですがnkfのコードも同じエラーになります)


何か良い方法がありましたら、ご教示いただけますと幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

昔作成した、自作変換関数なのでバグがありますが参考となれば
http://www.ken3.org/cgi-bin/test/test097-3.asp?DATA=%93%5D%90E
http://www.ken3.org/asp/backno/asp097.html
(※URIだと、スペースを+に直したり、&の処理とか、工夫が必要ですが。。。。)
MACでCreateObject("ScriptControl")などが使えないなら作ってしまえ・・の安易な発想でした。

vba

1Sub Test() 'google検索テスト 2 3 '検索文字を入力 4 Dim strMOJI As String 5 strMOJI = InputBox("キーワード=", "入力", "初日で辞めたくなった") 6 7 '検索文字を作る 8 Dim strPARA As String 'パラメーター 9 strPARA = testUTF8(strMOJI) '関数を呼ぶ 10 MsgBox strPARA 11 12 '手抜きで Shell でWebページを表示する 13 'Dim strURL As String 14 'strURL = "http://www.google.co.jp/search?hl=ja&ie=UTF-8&q=" & strPARA 15 'Call Shell("explorer.exe """ & strURL & """", vbNormalFocus) 16 17End Sub 18 19Function testUTF8(CHK_DATA) 20 21 '文字数分ループして、コードを表示 22 strUTF8 = "" '空文字で初期化 23 For n = 1 To Len(CHK_DATA) 24 strWORK = Mid(CHK_DATA, n, 1) 'n番目の文字を取り出す 25 '2バイト、漢字か判断 手抜きでLen関数で文字数を見た 26 If Len(Hex(Asc(strWORK))) <= 2 Then 27 If Asc(strWORK) <= &H20 Then 28 '制御コードか? 29 strCODE = "%" & Right("0" & Hex(Asc(strWORK)), 2) 30 Else 31 '英数はそのまま+する 32 strCODE = strWORK 33 End If 34 Else 35 strCODE = SJIStoUTF8(strWORK) '変換関数を呼ぶ 36 End If 37 strUTF8 = strUTF8 & strCODE '結果の文字列をつなげる 38 Next 39 40 'リターン値を代入 41 testUTF8 = strUTF8 42 43End Function 44 45'SJISコードの文字列を受け取り、UTF8コードの%付文字列を返す 46Function SJIStoUTF8(strSJIS) 47 48 strUNICODE = AscW(strSJIS) 'ASCWでユニコードにする 49 50 'コードを2進にしてワークに代入する 51 strWORK2 = HEX16toSTR2(Hex(strUNICODE)) 52 53 '切り取って、UTF8の2進数を作成する 54 'xxxx xxxx xxxx xxxx を下記に割り当てる 55 '1110xxxx 10xxxxxx 10xxxxxx 56 strUTF8CODE = "1110" & Mid(strWORK2, 1, 4) 57 strUTF8CODE = strUTF8CODE & "10" & Mid(strWORK2, 5, 6) 58 strUTF8CODE = strUTF8CODE & "10" & Mid(strWORK2, 11, 6) 59 60 '作成した2進数を16進数に戻す 61 strWORK16 = STR2toHEX16(strUTF8CODE) 62 63 '%を付けて格納 64 strRET = "" 'リターン値を初期化 65 strRET = strRET & "%" & Mid(strWORK16, 1, 2) '%を付けた文字列を作成 66 strRET = strRET & "%" & Mid(strWORK16, 3, 2) 67 strRET = strRET & "%" & Mid(strWORK16, 5, 2) 68 69 'リターン値を代入 70 SJIStoUTF8 = strRET 71 72End Function 73 74'HEX16進文字列を受け取り2進数文字列を返す 75Function HEX16toSTR2(strHEX) 76 77 Dim n 'ループカウンタ 78 Dim i 'ループのカウンタ 79 Dim n8421 '8 4 2 1の数値計算用 80 Dim str2STR 81 82 Dim nCHK 83 84 str2STR = "" '結果のエリアを初期化する 85 86 '文字数分ループする 87 For n = 1 To Len(strHEX) 88 On Error Resume Next 'エラー発生時次の行へ 89 nCHK = 0 '0で初期化 90 nCHK = CInt("&h" & Mid(strHEX, n, 1)) 'n文字目を数値変換 91 On Error GoTo 0 'エラー処理を通常に戻す 92 93 n8421 = 8 '初期値に8を代入する(上からチェックしたいので) 94 For i = 1 To 4 '4回まわるよ 95 If (nCHK And n8421) = 0 Then 'Andでビットをチェックする 96 str2STR = str2STR & "0" 'ビットは立ってないよ 97 Else 98 str2STR = str2STR & "1" 'ビットは立ってるよ 99 End If 100 '次のビットをチェックしたいので2で割る 101 n8421 = n8421 / 2 102 Next 103 Next 104 105 'リターン値をセットして終了 106 HEX16toSTR2 = str2STR 107 108End Function 109 110'2進文字列を受け取り16進文字列を返す 111Function STR2toHEX16(str2) 112 113 Dim strHEX 114 Dim n 'ループカウンタ 115 Dim i 'ループのカウンタ 116 Dim n8421 '8 4 2 1の数値計算用 117 Dim nBYTE 118 119 '頭4文字単位かチェックする 120 n = Len(str2) Mod 4 '足りない文字数を計算する 121 If n <> 0 Then 122 str2 = String(4 - n, "0") & str2 '頭に文字0を追加する 123 End If 124 125 strHEX = "" '結果のエリアを初期化する 126 127 '文字数分ループする 128 For n = 1 To Len(str2) Step 4 '4文字(1バイト)単位にループを作る 129 n8421 = 8 '初期値に8を代入する(上から計算したいので) 130 nBYTE = 0 '1バイト計算用変数を初期化 131 For i = 0 To 3 '4回まわるよ(4ビット分) 132 'ビットが立っているかチェックする 133 If Mid(str2, n + i, 1) = "1" Then 134 nBYTE = nBYTE + n8421 'ビットに対応した数値を+する 135 End If 136 '次のビットを計算したいので2で割る 137 n8421 = n8421 / 2 138 Next 139 '計算して、1倍との数値が完成したので16進文字にしてセットする 140 strHEX = strHEX & Hex(nBYTE) 141 Next 142 143 'リターン値をセットして関数を抜ける 144 STR2toHEX16 = strHEX 145 146End Function 147

投稿2020/04/01 10:16

ken3_rougai_pg

総合スコア32

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

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

ucndev

2020/04/01 14:21

ありがとうございます! 何がどうなっているのかコードを拝読してもまったく理解できませんが、まるっとコピーを使わせていただいたところ、意図通りの変換になりました!ありがとうございました!! 1つ、半角の「%」が「%25」にならずそのまま出力されておりましたが、「%25」にする方法がわからず、半角「%」を全角「%」に置換してからtestUTF8()に流すようにしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問