English help on website



SafeArrayの返り値について(Ver9.41対応版)
目次COMの呼び出し− SafeArrayの返り値について
COMオブジェクトの扱いは、JavaScript対応ができるまでは、秀丸マクロの文法に合わせるため、非常に面倒でした。
現在のバージョンでははJavaScriptで扱いやすくなっているので、新しくマクロを作る場合はJavaScriptを使うことをお勧めします。

以下は従来の秀丸マクロの文法についてのサンプルですが、末尾にJavaScriptのサンプルもあります。


COMオブジェクトが返す値として、いわゆるSafeArrayという種類の値で、配列をまるごと1つの返り値として返すことがあります。
例えば"Scripting.Dictionary"オブジェクトの"Keys"や"Items"がそれにあたります。
秀丸マクロではSafeArrayをそのまま表現することができないため、SafeArrayを受け取ったときは自動的にオブジェクトに変換しています。(V8.98以降)
オブジェクトは、"Count"で要素数、"Item"で要素の内容を取得できるオブジェクトになっています。

サンプル
    newfile;
    
    #objDic = createobject("Scripting.Dictionary");
    callmethod #objDic, "add", "Key1", "Value1";
    callmethod #objDic, "add", "Key2", 2;
    callmethod #objDic, "add", 3, "Value3";
    
    #objKeys = member(#objDic, "Keys"); //ここでオブジェクトに変換される
    #c = getpropnum(#objKeys, "Count"); //"Count"で要素数
    #i = 0;
    insert "Keys:"+str(#c)+"\n";
    while(#i<#c){
        $key = getpropstr(#objKeys, "Item", #i); //"Item"で要素
        if(getresultex(10)!=false){
            insert "[\""+$key+"\"]=";
            $a = getpropstr(#objDic, "Item", $key);
            if(getresultex(10)!=false){
                insert "\""+$a+"\"";
            } else {
                #a = getpropnum(#objDic, "Item", $key);
                if(getresultex(10)!=false){
                    insert str(#a);
                }
            }
            insert "\n";
            #i=#i+1;
            continue;
        }
        #key = getpropnum(#objKeys, "Item", #i); //"Item"で要素
        if(getresultex(10)!=false){
            insert "["+str(#key)+"]=";
            $a = getpropstr(#objDic, "Item", #key);
            if(getresultex(10)!=false){
                insert "\""+$a+"\"";
            } else {
                #a = getpropnum(#objDic, "Item", #key);
                if(getresultex(10)!=false){
                    insert str(#a);
                }
            }
            insert "\n";
            #i=#i+1;
            continue;
        }
        #i=#i+1;
    }
    endmacro;


JavaScriptでScripting.Dictionaryをする場合のサンプル
newfile;
js{
    objDic = createobject("Scripting.Dictionary");
    objDic.add( "Key1", "Value1" );
    objDic.add( "Key2", 2 );
    objDic.add( 3, "Value3" );
    objDic.Item("Key4") = 4 ;//引数付きプロパティ設定も可能
    objDic.Item("Key5") = "Value5";//引数付きプロパティ設定も可能
    
    objKeys = objDic.Keys().toArray();//SafeArrayをjsの配列に
    c = objKeys.length;//objKeys.Count;ではなくjsの配列
    i = 0;
    insert( "Keys:"+c+"\n" );
    while(i<c){
        key = objKeys[i];//Itemではなくjsの配列になっている
        if(key){
            insert( "[\""+key+"\"]=" );
            a = objDic.Item(key);
            if(a){
                insert( "\""+a+"\"" );
            } else {
                a = objDic.Item(key);
                if(a){
                    insert(a);
                }
            }
            insert("\n");
        }
        i++;
    }
}
endmacro;

JavaScriptの{}のオブジェクトはハッシュなので、Scripting.Dictionaryを使わずに{}をを使うと非常に簡潔に書くことができます。

JavaScriptのオブジェクトのサンプル1

//JScriptでも通るfor(...in...)
js{
    objDic={};//オブジェクト=ハッシュ
    objDic.Key1="Value1";
    objDic.Key2=2;
    objDic[3]= "Value3";
    objDic["Key4"] = 4 ; //KeyX=でも、["KeyX"]=でもいける
    objDic["Key5"] = "Value5" ;
    
    //個数はc=0;for( key in objDic) {c++;}だけど必要ない
    for( key in objDic) {
        insert( "[\""+key+"\"]=" +objDic[key]+"\n" );
    }
}
endmacro;
JavaScriptのオブジェクトのサンプル2
//配列でやる場合はWebView2が必要
jsmode "WebView2";
js{
    objDic={};//オブジェクト=ハッシュ
    objDic.Key1="Value1";
    objDic.Key2=2;
    objDic[3]= "Value3";
    objDic["Key4"] = 4 ; //KeyX=でも、["KeyX"]=でもいける
    objDic["Key5"] = "Value5" ;
    
    keys=Object.keys(objDic);//この文法はWebView2が必要
    insert("Keys:"+keys.length+"\n");
    for( i=0;i<keys.length;i++) {
        insert( "[\""+keys[i]+"\"]=" +objDic[keys[i]]+"\n" );
    }
}
endmacro;