<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://www.haijin-boys.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=138.101.21.146</id>
	<title>MeryWiki - 利用者の投稿記録 [ja]</title>
	<link rel="self" type="application/atom+xml" href="https://www.haijin-boys.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=138.101.21.146"/>
	<link rel="alternate" type="text/html" href="https://www.haijin-boys.com/wiki/%E7%89%B9%E5%88%A5:%E6%8A%95%E7%A8%BF%E8%A8%98%E9%8C%B2/138.101.21.146"/>
	<updated>2026-06-13T10:11:50Z</updated>
	<subtitle>利用者の投稿記録</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.haijin-boys.com/wiki/index.php?title=%E3%83%9E%E3%82%AF%E3%83%AD%E8%A6%9A%E3%81%88%E6%9B%B8%E3%81%8D%EF%BC%88%E9%96%8B%E7%99%BA%E8%80%85%E5%90%91%E3%81%91%EF%BC%89&amp;diff=4406</id>
		<title>マクロ覚え書き（開発者向け）</title>
		<link rel="alternate" type="text/html" href="https://www.haijin-boys.com/wiki/index.php?title=%E3%83%9E%E3%82%AF%E3%83%AD%E8%A6%9A%E3%81%88%E6%9B%B8%E3%81%8D%EF%BC%88%E9%96%8B%E7%99%BA%E8%80%85%E5%90%91%E3%81%91%EF%BC%89&amp;diff=4406"/>
		<updated>2019-06-19T02:59:13Z</updated>

		<summary type="html">&lt;p&gt;138.101.21.146: /* マクロからファイル選択ダイアログ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= 概要 =&lt;br /&gt;
マクロ開発者向けの覚え書きです．&amp;lt;br&amp;gt;&lt;br /&gt;
リファレンスなどに載っていない，豆知識的なことを集めています．&lt;br /&gt;
&lt;br /&gt;
= 覚え書き =&lt;br /&gt;
&lt;br /&gt;
== 開発言語について ==&lt;br /&gt;
WSH（Windows Script Host) が対応している言語であれば利用が可能です．&amp;lt;br&amp;gt;&lt;br /&gt;
標準では JScript（≒javascript）と VBScript が入っています．&amp;lt;br&amp;gt;&lt;br /&gt;
他の言語（Perl や Python）もインストールすれば使えますが，一般配布する場合利用者もインストールが必要になります．&amp;lt;br&amp;gt;&lt;br /&gt;
どの言語でも良いですが，JScript での開発者が多いため，JScript の方が情報が集まりやすくお勧めです．&lt;br /&gt;
&lt;br /&gt;
== マクロを保存する際の文字コード ==&lt;br /&gt;
基本的に単体で利用する場合はどの文字コードでも構いません．&amp;lt;br&amp;gt;&lt;br /&gt;
ただし「他のマクロから読まれる」場合は文字コードの選択が重要になります．&amp;lt;br&amp;gt;&lt;br /&gt;
今のマクロでは #title のようなプリプロセス処理が必要で，それに対応したロードができる include ライブラリの IO.Include はデフォルトで UTF-8 対応なので，UTF-8 をお勧めします（個別の指定は可能）．&amp;lt;br&amp;gt;&lt;br /&gt;
ただし読み込む側が FileSystemObject を利用している場合，SJIS/Unicode しか対応できないのでその場合は SJIS をお勧めします（Mery 1 時代のマクロなどはコレです）．&lt;br /&gt;
&lt;br /&gt;
== window.Document と Editor.ActiveDocument の違い ==&lt;br /&gt;
window.Document は，マクロ開始時にアクティブなドキュメントを指し続けます．マクロで別のドキュメントを Activate しても変わりません．&amp;lt;br&amp;gt;&lt;br /&gt;
Editor.ActiveDocument は，その時点でアクティブなドキュメントを指します．マクロで別のドキュメントを Activate すると当然変わります．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
Editor.Documents.Item(0).Activate();&lt;br /&gt;
Alert(Document.Name);&lt;br /&gt;
Alert(Editor.ActiveDocument.Name);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
また，window.Document は Documents.Item() と一致しませんが，Editor.ActiveDocument は一致します．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
for (var i=0; i&amp;lt;Editor.Documents.Count; i++) {&lt;br /&gt;
  if (Editor.ActiveDocument == Editor.Documents.Item(i)) {&lt;br /&gt;
    Alert(&amp;quot;Editor.ActiveDocument が一致&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  if (Document == Editor.Documents.Item(i)) {&lt;br /&gt;
    Alert(&amp;quot;window.Document が一致&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== window.Redraw = true は必要か ==&lt;br /&gt;
マクロで&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
Redraw = false;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
にしたとき，最後&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
Redraw = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
が必要かという点については，現状確認する限りでは不要です．&lt;br /&gt;
&lt;br /&gt;
== 矩形選択の扱い ==&lt;br /&gt;
マクロで矩形選択は扱えません（プラグインですら無理）．&amp;lt;br&amp;gt;&lt;br /&gt;
ただし，矩形選択中かの判定だけは以下の方法で可能です．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var s = Document.Selection;&lt;br /&gt;
var isBoxed = (s.GetBottomPointY(mePosView) - s.GetTopPointY(mePosView)) != (s.Text.match(/\n/g) || []).length;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2019/06/11追記（有志）：使い道は限られますが、Alt + Shit + カーソル移動のキーコードを送ることで、矩形範囲指定の開始と範囲変更は可能です。&lt;br /&gt;
  new ActiveXObject(&amp;quot;WScript.Shell&amp;quot;).SendKeys(&amp;quot;+%{left}&amp;quot;);//{right},{up},{down}&lt;br /&gt;
&lt;br /&gt;
== Document.GetLines の引数 ==&lt;br /&gt;
リファレンスには &#039;&#039;&#039;meGetLineView&#039;&#039;&#039; しか書かれていませんが，論理行単位での行数取得には引数に 0 を渡します．&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;meGetLineLogical&#039;&#039;&#039; という定数はありません．&lt;br /&gt;
&lt;br /&gt;
== プリプロセス（#title など） ==&lt;br /&gt;
対応しているプリプロセスコードは以下の通りです．&lt;br /&gt;
* #icon = &amp;quot;****&amp;quot; [, アイコン番号]&lt;br /&gt;
* #title = &amp;quot;****&amp;quot;&lt;br /&gt;
* #tooltip = &amp;quot;****&amp;quot;&lt;br /&gt;
* #include &amp;quot;****.js&amp;quot;&lt;br /&gt;
これらは必ずファイル先頭に書かなければなりません（コメントや VBS の Option Explicit などよりも先）．&lt;br /&gt;
&lt;br /&gt;
== 他のファイルのロード方法 ==&lt;br /&gt;
マクロから他のファイルを直接ロードするには以下の方法があります．&lt;br /&gt;
* FileSystemObject を利用する&lt;br /&gt;
* ADODB.Stream を利用する&lt;br /&gt;
* include ライブラリの IO クラスを利用する&lt;br /&gt;
&lt;br /&gt;
=== FileSystemObject を利用する ===&lt;br /&gt;
コードが短く簡単に扱えます．&amp;lt;br&amp;gt;&lt;br /&gt;
また FileSystemObject 自体に，ファイルの有無やフォルダ作成の機能があります．&amp;lt;br&amp;gt;&lt;br /&gt;
ただし扱える文字コードは SJIS または Unicode 限定．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Scripting.FileSystemObject の定数&lt;br /&gt;
var ForReading = 1;           // ファイルを読み取り専用として開きます。このファイルには書き込むことができません。&lt;br /&gt;
var ForWriting = 2;           // ファイルを書き込み専用として開きます。&lt;br /&gt;
var ForAppending = 8;         // ファイルを開き、ファイルの最後に追加して書き込みます。&lt;br /&gt;
var TristateUseDefault = -2;  // システム デフォルトを使ってファイルを開きます。&lt;br /&gt;
var TriStateTrue = -1;        // ファイルを Unicode ファイルとして開きます。&lt;br /&gt;
var TristateFalse = 0;        // ファイルを ASCII ファイルとして開きます。&lt;br /&gt;
&lt;br /&gt;
var fso = new ActiveXObject(&amp;quot;Scripting.FileSystemObject&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// ファイルの読み込み&lt;br /&gt;
var fsIn = fso.OpenTextFile(Document.FullName, ForReading, false, TristateUseDefault);&lt;br /&gt;
var text = fsIn.ReadAll();&lt;br /&gt;
fsIn.Close();&lt;br /&gt;
Alert(text);&lt;br /&gt;
&lt;br /&gt;
// ファイルの書き込み&lt;br /&gt;
var fsOut = fso.OpenTextFile(&amp;quot;hoge.txt&amp;quot;, ForWriting, true, TristateUseDefault);&lt;br /&gt;
fsOut.Write(text);&lt;br /&gt;
fsOut.Close();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADODB.Stream を利用する ===&lt;br /&gt;
書き方は若干複雑ですが，システムが対応している文字コードであれば全て扱えます．&amp;lt;br&amp;gt;&lt;br /&gt;
また（信頼性は低いが）文字コードの自動判定も可能です．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var adTypeBinary = 1;           // バイナリ データを表します。&lt;br /&gt;
var adTypeText = 2;             // 既定値です。Charset で指定された文字セットにあるテキスト データを表します。&lt;br /&gt;
var adReadAll = -1;             // 既定値です。現在の位置から EOS マーカー方向に、すべてのバイトをストリームから読み取ります。これは、バイナリ ストリームに唯一有効な StreamReadEnum 値です。&lt;br /&gt;
var adReadLine = -2;            // ストリームから次の行を読み取ります (LineSeparator プロパティで指定)。&lt;br /&gt;
var adSaveCreateNotExist = 1;   // 既定値です。FileName パラメータで指定したファイルがない場合は新しいファイルが作成されます。&lt;br /&gt;
var adSaveCreateOverWrite = 2;  // FileName パラメータで指定したファイルがある場合は、現在開かれている Stream オブジェクトのデータでファイルが上書きされます。&lt;br /&gt;
&lt;br /&gt;
// ファイルの読み込み&lt;br /&gt;
var adodb = new ActiveXObject(&#039;ADODB.Stream&#039;);&lt;br /&gt;
adodb.Type = adTypeText;&lt;br /&gt;
adodb.Charset = &#039;utf-8&#039;;&lt;br /&gt;
adodb.Open();&lt;br /&gt;
adodb.LoadFromFile(Document.FullName);&lt;br /&gt;
var text = adodb.ReadText(adReadAll);&lt;br /&gt;
adodb.Close();&lt;br /&gt;
Alert(text);&lt;br /&gt;
&lt;br /&gt;
// ファイルの書き込み&lt;br /&gt;
var adodb = new ActiveXObject(&#039;ADODB.Stream&#039;);&lt;br /&gt;
adodb.Type = adTypeText;&lt;br /&gt;
adodb.Charset = &#039;utf-8&#039;;&lt;br /&gt;
adodb.Open();&lt;br /&gt;
adodb.WriteText(text);&lt;br /&gt;
adodb.SaveToFile(&amp;quot;hoge.txt&amp;quot;, adSaveCreateOverWrite);&lt;br /&gt;
adodb.Close();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== include ライブラリの IO クラスを利用する ===&lt;br /&gt;
ファイルの読み書きを簡単にするクラスです．&amp;lt;br&amp;gt;&lt;br /&gt;
簡単に扱えることと，BOM なしの UTF-8 を書き込めることがメリットです．&amp;lt;br&amp;gt;&lt;br /&gt;
逆にソースを読むしか資料がないこと，ユーザに導入してもらう必要があるのが欠点です．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;include/IO.js&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// ファイルの読み込み&lt;br /&gt;
var text = IO.LoadFromFile(Document.FullName, &amp;quot;utf-8&amp;quot;);&lt;br /&gt;
Alert(text);&lt;br /&gt;
&lt;br /&gt;
// ファイルの書き込み&lt;br /&gt;
IO.SaveToFile(&amp;quot;hoge.txt&amp;quot;, text, &amp;quot;utf-8&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 他のマクロの実行方法 ==&lt;br /&gt;
他のマクロを実行するには，以下の方法があります．&lt;br /&gt;
* #include で取り込む&lt;br /&gt;
* ファイルをロードして eval する&lt;br /&gt;
前者は先頭でしかかけない上，動的にロードの切り替えができません．&amp;lt;br&amp;gt;&lt;br /&gt;
後者は文字コードの問題とプリプロセス処理に関する問題があります．&amp;lt;br&amp;gt;&lt;br /&gt;
include ライブラリの IO.Include を使うことで，プリプロセス処理に関しては解決できます．&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;include/IO.js&amp;quot;&lt;br /&gt;
&lt;br /&gt;
eval(IO.Include(&amp;quot;test.js&amp;quot;, &amp;quot;utf-8&amp;quot;)); // #include なども処理される&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== マクロからファイル選択ダイアログ ==&lt;br /&gt;
できません．&amp;lt;BR&amp;gt;&lt;br /&gt;
2019/06/11追記(有志)：以下の関数で可能です。&lt;br /&gt;
  function OpenFileDlg(){&lt;br /&gt;
    var HTASource = &#039;&amp;lt;object id=HtmlDlgHelper classid=CLSID:3050f4e1-98b5-11cf-bb82-00aa00bdce0b&amp;gt;&amp;lt;/object&amp;gt;\n&#039;&lt;br /&gt;
    +&#039;&amp;lt;script language=vbscript&amp;gt;\n&#039;&lt;br /&gt;
    +&#039;resizeTo 0,0\n&#039;&lt;br /&gt;
    +&#039;Sub window_onload()\n&#039;&lt;br /&gt;
    +&#039;CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;).GetStandardStream(1).Write HtmlDlgHelper.object.openfiledlg(,,&amp;quot;All Files(*.*)|*.*|&amp;quot;,&amp;quot;ファイル選択&amp;quot;)\n&#039;&lt;br /&gt;
    +&#039;close\n&#039;&lt;br /&gt;
    +&#039;End Sub\n&#039;&lt;br /&gt;
    +&#039;&amp;lt;/script&amp;gt;\n&#039;&lt;br /&gt;
    +&#039;&amp;lt;hta:application caption=no showintaskbar=no /&amp;gt;\n&#039;;&lt;br /&gt;
    &lt;br /&gt;
    var oExec = new ActiveXObject(&#039;WScript.Shell&#039;).Exec(&lt;br /&gt;
      &#039;MSHTA.EXE &amp;quot;javascript:new ActiveXObject(\&#039;Scripting.FileSystemObject\&#039;).GetStandardStream(0).ReadAll()&amp;quot;&#039;&lt;br /&gt;
    );&lt;br /&gt;
    oExec.StdIn.Write(HTASource);&lt;br /&gt;
    oExec.StdIn.Close();&lt;br /&gt;
    &lt;br /&gt;
    var filename = oExec.StdOut.ReadAll();&lt;br /&gt;
    var nullcharAt = filename.indexOf(String.fromCharCode(0x0));&lt;br /&gt;
    if (nullcharAt &amp;gt; 0) filename = filename.substring(0, nullcharAt);&lt;br /&gt;
    return filename;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
使用例&lt;br /&gt;
  var filename = OpenFileDlg();&lt;br /&gt;
  window.alert((filename)?filename:&#039;Canceled&#039;);&lt;br /&gt;
&lt;br /&gt;
2019/06/17追記(有志)：PoserShell版追加,,2019/06/19修正：Execと標準出力の組み合わせを、Runとクリップボードに変更&amp;lt;br&amp;gt;&lt;br /&gt;
HtmlDlgHelper.object.openfiledlg の第1引数はダイアログに初期表示する InitFile。疑似的に初期フォルダを指定することが可能だが、パス区切り文字 &amp;quot;\&amp;quot; で終わることはできない。PowerShell 版なら初期フォルダの明示、複数ファイル選択が可能。Multiselect = $false にしても $dialog.FileName に書き換えせずに $dialog.FileNames でアクセス可能。&lt;br /&gt;
  function OpenFileDlg(){&lt;br /&gt;
    ClipboardData.ClearData();&lt;br /&gt;
    var PS1Source = &#039;[void][System.Reflection.Assembly]::LoadWithPartialName(\&#039;System.windows.forms\&#039;);&#039;&lt;br /&gt;
                  +&#039;$dialog = New-Object System.Windows.Forms.OpenFileDialog;&#039;&lt;br /&gt;
                  +&#039;$dialog.Filter = \&#039;AllFiles(*.*)|*.*\&#039;;&#039;&lt;br /&gt;
                  +&#039;$dialog.InitialDirectory = \&#039;C:\\\&#039;;&#039;&lt;br /&gt;
                  +&#039;$dialog.Title = \&#039;ファイル選択\&#039;;&#039;&lt;br /&gt;
                  +&#039;$dialog.Multiselect = $true;&#039;&lt;br /&gt;
                  +&#039;if($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){ Set-Clipboard $dialog.FileNames }&#039;&lt;br /&gt;
    new ActiveXObject(&#039;WScript.Shell&#039;).Run(&lt;br /&gt;
        &#039;PowerShell.EXE -sta -ExecutionPolicy RemoteSigned &#039; + PS1Source, 0, true&lt;br /&gt;
    );&lt;br /&gt;
    var result=ClipboardData.GetData();&lt;br /&gt;
    ClipboardData.ClearData();&lt;br /&gt;
    return result;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Prompt で空入力とキャンセルの区別 ==&lt;br /&gt;
できません．&lt;br /&gt;
&lt;br /&gt;
== PopupMenu.Add の ID ==&lt;br /&gt;
PopupMenu.Add() の ID は必ず 0 以外にしましょう．&amp;lt;br&amp;gt;&lt;br /&gt;
PopupMenu.Track() はキャンセルされた（メニューが押されなかった）場合，0 を返します．&lt;/div&gt;</summary>
		<author><name>138.101.21.146</name></author>
	</entry>
</feed>