0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GASに日本語をpostする

Last updated at Posted at 2019-07-18

##目的
Excel VBAからpost経由でGASに日本語を送りつけたい。
転送データは最終的にスプレッドシートに保存する。

##対応

  1. Excel VBA(Shift-JIS)
  2. COM経由でDLL呼び出し(UTF-16に変換、コードユニットに変換する)
  3. POSTする
  4. GASで受け取ったコードユニットを文字列変換
  5. スプシに書き込み

##詳細
GASのREST APIを使ってpostできるが、英数字のみ送信可能。
BASE64とか使えよって話なんだけどね。

Excel VBAから送る要件があったのと、GAS側であまり処理時間かけたくなかったので簡易的な実装を行った。
VBAから直接日本語を送ると、Shift-JISなのでGAS側で文字として扱えない。
そこでGAS(というよりもJSの内部表現の話)で使っているUTF-16に変換する必要がある。

VBAでは.Netの処理がフルに使えないので、C#でサクっと作成。

###C#側

変換.cs
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace CCC
{
    [ComVisible(true)]
    public interface ICCC
    {
        [Description("文字列をユニコード表記に変換する")]
        string ConvertUnicodeCode(string target);
    }

    [ClassInterface(ClassInterfaceType.None)]
    public class CCC:ICCC
    {

        public string ConvertUnicodeCode(string target)
        {
            String str = target;
            if (str == null)
            {
                Console.Write("input arg. ex) ccc.exe \"No problem. Everything's fine.\"");
                return "none";
            }

            string retStr = "";

            char[] chars = str.ToCharArray();
            foreach (char c in chars)
            {
                retStr += String.Format("{0:x4}", (int)c);
            }

            return retStr;
        }
    }
}

intにキャストするだけでコードユニットとれるって便利。
参考にした記事

注意点は
・インターフェースを実装する事
・[できたライブラリを64bitなのか32bitかで合わせてレジストリに登録する事]
(https://qiita.com/aoi_erimiya/items/aa9160017660b1830891)

###VBA側

conv.vb
    'パラメータ
    Dim str_Parameter As String
    str_Parameter = POST_CSV_Convert(str_SheetName)
        
    '文字コードをUnicodeコード表記に変換
    Application.StatusBar = "送信情報をエンコードしています..."
    Dim cuc As New CCC.CCC
    
    Dim encodeDat As String
    encodeDat = "data=" & cuc.ConvertUnicodeCode(str_Parameter)
        
    '--------------
    'POST実行
    '--------------
    DoEvents
    Dim xmlhttp As Object
    Set xmlhttp = CreateObject("msxml2.xmlhttp")
    xmlhttp.Open "POST", url, False
    xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    xmlhttp.send (encodeDat)

登録したDLLを呼び出して使う。

注意点は
postのパラメータ名(data=とか)の部分は変換しない。
GASで受け取れなくなるので。

参考文献

###GAS側

変換.js
function codeConvert(charCodeStr) {
  uniString = [];

  var idx = 0;
  while(idx < charCodeStr.length){
    var sliceChar = String.fromCharCode("0x" + charCodeStr.slice(idx, idx + 4))
    uniString.push(sliceChar);
    idx = idx + 4;
  }
  return uniString.join('');
}

function doPost(e) {
  var paramData = '' + e.parameters.data;
  var datas = codeConvert(paramData).split(':');

  // スプシに書き込みとか
}

受け取ったコードユニットを4文字毎に切り出して、String.fromCharCode()を使う。

##課題
日本語のやり取りはできるようになったけど、どうしても転送量が増えてしまう。
一回で済んでたところを、分割して送信せなあかん場合もある。
zipかなにかしてやりたい。
あとは、コードユニットに変換しただけでほぼ平文なので、重要な情報を扱う際には何かしら暗号化もしてあげればよいかなーと思う。

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?