ここでのマクロとは表次郎を任意の処理で動くように記述しておくと処理を呼び出すだけで
自動的に行うようにする機能です。
記述の雰囲気はC風にしています。
例としては下記のように条件文などは大括弧"{"、"}"で囲んだり、命令の最後にはセミコロン";"を記述します。
また、大文字と小文字は別ものと判断します。「int」と「Int」は別ものです。
変数定義やコメントなんかも//や/* */で記述するあたりも似た感じにしています。
ただし、記述できることはかなり少ないので注意ください。
int i; // コメント i = input("数値",1,""); if(i == 5){ cell(1,2) = "Hello World"; } |
記述したソースを「表次郎」のメニュー「マクロ」-「マクロの登録」から「表次郎マクロ登録」画面から
ソースをコンパイルすることで「表次郎」のメニュー「マクロ」-「マクロの実行」またはショートカットの
[Ctl]+[M]からマクロ実行画面を表示して登録したマクロ名を選択して実行すると
ソースの内容に従った処理を実行します。
必須の作業ではないですがソースの最初にマクロの説明文を記述します。
"//"の命令は記述後、行間でコメントとして判断するので自由に文章を記述できます。
マクロに対する内容など書いておくとどんな機能であったかを思い出すことが出来るので
記述することをおすすめします。
次にシステム的に意味しますが
先頭行から順に"//"で記述して"<処理説明>"というキーワードを見つけたら
該当行以降のコメントで"//"が切れた時点もしくは"//"のみの記述になるまでの文章を
表次郎マクロ登録の「ファイル選択」した時点で「処理説明」に文章を取り込みます。
編集モードがOFFのときはコンパイルボタン押下時にも読込ます。
指定したファイルのソースを読み込みます。
inlucdeファイルはソースファイルと同フォルダ直下のファイルを取得、無ければ実行ファイルを
入れたフォルダの「macro」フォルダを検索します。
また、ソース上には記述しないですがファイルの拡張子は「.hsh」のもののみが対象となります。
※ブックマクロから読み込む場合は「macro」フォルダのもののみ対象となります。
※#includeの記述は必ず行の先頭から指定してください。
変数とは値を保持する領域ですが文字列を扱いたい場合は"string"、
整数を扱いたい場合は"int"といった風に領域を確保します。
記述方法は型の種類、文字列
プログラムを記述していきます。
記述した順番に表次郎を操作する命令を記述していきます。
命令については一覧を参考ください。
【命名規則について前提(いいわけ?)】
本来最初に決めてユーザーの付ける名称とシステム側で付ける名前が
ぶつからないようにするために命名規則を設けると思います。
ただ、基本的にユーザーがいないので自分のなかでもうけたルール
だけで作ってましたがマクロについての要望がユーザー側から
あったことから命名規則を文面化しておこうかなという
気分になったので作ることにしました。
(2024/07/16記述、マクロ公開から数年たっている)
何がいいたいかというと命名規則といいながら一部結構な部分もあること。
includeファイルの関数については現状の命名はあまりよくないのですが
使っていることもあって存在は残すのですが
今後は修正しようかなと考えているということです。
以上、注意ください。
あと、アドオンマクロで作者がマクロを作ってるわけですが
命名はかなり適当な面もあるので見本ではないので注意ください。
【システム側で付ける名称】
・命令関係は小文字で統一。(例外:RGB())
文字列と文字列の区切りをアンダーバー
・定数(表次郎的にはシステム側が事前に値を割り振った変数)では
大文字で統一。(例外:true, false)
文字列と文字列の区切りをアンダバー
・includeで取り込む関数:頭に"func_"を付けるようにして小文字で統一。
文字列と文字列の区切りをアンダーバー
※例外としてcalendr.hsh, tool.hshで定義している関数は除く
(利用している処理もあるのでファイルそのものは残す。)
・include内で使うグローバル変数は値をセットする関数名の頭に"g_"
を付けて関数名の後ろにそれぞれの変数名を記述する。
例:関数func_get_cell_range()で使うグローバール変数はg_func_get_cell_range_col1など
【ユーザー側推奨の名称】
・基本的には大文字小文字を混ぜた名前の場合は問題なしとする。
※例外としてcalendr.hsh, tool.hshのincludeファイルで定義している
関数名は大文字小文字が混合したものになりますがルールなき時代のもので
多分普通には名前がかぶることはないと思います。
今後はシステム側が用意するものとしては大文字小文字の混合の名称は用意
しないようにしたいと思っています。
・ローカル変数名:
プレフィックス的な変数名。
厳密に変数の頭に型を書いてほしいというわけではなく
大文字小文字を混ぜた変数にしてもらうという意味です。
・グローバル変数名:
小文字のみにする場合で頭に"g_"を付ける場合、"g_func_"とならないようにする。
・定数は大文字で頭に"C_"を付けるようにする。
・関数の引数の名前はもし小文字だけにするなら頭に"i_"を付ける。
(大文字小文字を混ぜるなら問題なし)
※作者は関数パラメータは小文字だけの略字にすることが多いですが
絶対に関数に名前を付けない自信があるからなので小文字だけに
するなら"i_"を付けた方が無難です。
作者が良くパラメータに小文字だけで指定してる名前の例は
stringのデータならstrとか長さならlen、セルの位置はcol,rowなど
str、lenについては関数で発生しそうですが既にstring, lengthと
いう命令があるので短縮名の関数は用意するつもりはありません。
プログラムを見たとき内容を理解しやすくするための注釈です。
書き方は"//"の後ろに書く内容が行内でコメントとなります。
複数行をコメントにする場合は開始"/*"からコメントの最後は"*/"
string aaa; // ここがコメント行です。 /* 複数行の コメントです。 */ |
変数はユーザーが値を任意に保持したりする領域です。
変数名は任意に入力出来ます。
・intなど既に定義されている名前は使用出来ません。
・数字のみの変数も使用出来ません。
string aaa; int XXXX; double bb; date dt; aaa = "Hello"; XXXX = 3; bb = 3.5; dt = "2021/01/31"; |
型 | 内容 |
---|---|
string | 文字列 |
int | 整数 |
double | 実数 |
date | 日付 |
sheet | 扱うシートを指定する場合に使用する。 |
型が異なるものも代入できるものについては自動で変換します。
ただし、数値の変換に文字列を入れるなど変換できないものについては
実行時にエラーとなります。
int a; string txt; txt = "123"; a = txt; cell(1,1) = a; >結果:123 txt = "ABC"; a = txt; ←エラー |
数値を扱う際はint型とdouble型を使用しますがint型に
小数点を入れた場合は切り捨てられます。
int a; a = 1.23; cell(1,1) = a; >結果:1 ← aは整数なので小数点部分は切り捨てられます double b; b = 1.23; cell(1,1) = b; >結果:1.23 b = 1 / 3; cell(1,1) = b; >結果:0 ← 計算時点で整数として判断される b = 1.0 / 3; cell(1,1) = b; >結果:0.333333333333333 ← 1.0と入力でdobule扱いする string s; s = "1"; cell(1,1) = s / 3; >結果:0.333333333333333 |
シート型は他の変数と違った扱い方をします。
変数にシート名を指定して特定の関数の頭に
変数をピリオドで付けると該当の関数は指定したシート上のデータを扱う
ことが出来ます。
シートの指定がない場合は実行時にエラーとなります。
使用できる関数は一覧表の「SHEET指定」が「○」のものとなります。
指定しない場合は開いているシート上のデータを対象とします。
sheet st; st = "Sheet1"; // シート名が「Sheet1」のシートを指定 st.cell(1,2) = "Hello"; |
文字列型に値をセットする方法はダブルコーテーション、または
シングルコーテーションで囲んだ内容がデータとして扱われます。
データ内にダブルコーテーションまたはシングルコーテーションが
ある場合はダブルコーテーションで囲んでいる場合は
ダブルコーテーションを2つ並べて書くと1文字のダブルコーテーション
として扱います。
改行文字は"\n"で書きます。
"\\"を書くと"\"になります。
タブ文字は当処理では扱えません。
cell(1,1) = "Hello"; // ダブルコーテーションで囲んだ例 ↓ Hello ----------------------------------------- cell(1,1) = """あいう"""; // "あいう"をデータとする例 cell(1,1) = '"あいう"'; // "あいうをデータとする例2 ↓ "あいう" ------------------------------------------ cell(1,1) = "Hello\n改行"; // セル内で\nは改行 ↓ Hello 改行 ----------------------------------------- cell(1,1) = "\\n"; // \nを内容とする場合 ↓ \n ---------------------------------------- cell(1,1) = "\\"; // \となる ↓ \ |
関数外の処理の最初に定義する変数をグローバル変数
関数内に定義を行うとローカル変数となります。
関数ごとに同じ名前の変数を定義しても別の値として扱ってくれます。
int 値; // グローバル変数 値 = 10; void test() { int 値; // ローカル変数 値 = 15; cell(2,1) = 値; } cell(1,1) = 値; test(); cell(3,1) = 値; // ローカル変数の値は反映しない --結果----------------------- 10 15 10 |
if(条件式){ 命令; } else { 命令; } |
if()文の条件式が条件を満たす(true)場合は大括弧で囲った範囲内に記述した命令を実行します。
「条件以外」(false)の場合はelse文後の大括弧で囲った範囲に記述した命令を実行します。
elseの記述は任意です。
条件 | 内容 |
---|---|
「a == b」または 「a = b」 |
aとbが一致するときはtrue、以外はfalse |
「a <= b」 | aとbが同じかaよりbが大きいときはtrue、以外はfalse |
「a < b」 | aよりbが大きいときはtrue、以外はfalse |
「a >= b」 | aとbが同じかaがbより大きいときはtrue、以外はfalse |
「a > b」 | aがbより大きいときはtrue、以外はfalse |
「a <> b」または 「a != b」 |
aとbが一致しないときtrue、以外はfalse |
意味 | 内容 |
---|---|
「かつ」 | 「and」または「&&」 |
「または」 | 「or」または「||」 |
世間のプログラムに出来て表次郎に出来ないこと。
・ORまたはANDの条件は5つまで可能です。
・ANDとORではANDを優先します。
・条件内で()での優先度を変更することは出来ません。
・if()文やelseの後は命令が1つであっても必ず大括弧で囲んでください。
int a; // ANDの例 aが1から9または30から39のとき実行する a = 3; if(a >= 1 and a <= 9 or a >= 30 and a <= 39){ 命令; } |
int a, b; // b=1かつaが1または10のとき実行する // if(b == 1 and (a == 1 or a == 10)){ // のような書き方は出来ないので下記のandとorを // 分ける必要がある。 a = 1; b = 1; if(b==1){ if(a == 1 or a == 10){ 命令; } } |
int flag; flag = 0; if(a == 1){ flag = 1; } else if(a == 3){ flag = 1; } else if(a == 4){ flag = 1; } else { flag = 2; } if(flag == 1{ 命令; } |
while(条件式){ 命令; } |
while()文の条件式が条件を満たす(true)場合は大括弧で囲った範囲内に記述した命令を
条件以外になるまで実行を繰り返します。
条件式はif()文と同じです。
また、while()の命令の中にbreak;を記述するとループを抜けます。
世間のプログラムに出来て表次郎に出来ないこと。
・for()文はないのでwhile()文を使用してください。
・無限ループにならないように注意ください。
表次郎では特定の処理回数を超えたら警告が発生します。
int row, max; max = get_row_max(); row = 1; while(row <= max){ 命令; row = row + 1; } |
while(row <= get_row_max())という記述は可能ですが
命令の中にセルを更新する処理があり常に最大行数がUPする
ような処理の場合は無限ループになるのでサンプルのように
変数に最大数を取得してあるほうを推奨します。
int row, row_max; int col, col_max; col_max = get_col_max(); row_max = get_row_max(); row = 1; while(row <= row_max){ col = 1; while(col <= col_max){ 命令; col = col + 1; } row = row + 1; } |
int row; row = 1; while(row <= 10) { if(条件){ break; ←条件に一致したらループを抜ける } 命令; row = row + 1; } |
int a; double b, c; a = 1 + 2; cell(1,1) = a; ← 3 b = 10 / 3; cell(2,1) = b; ← 3(注意:10が整数なので整数と判断される) b = 10.0 / 3; cell(3,1) = b; ← 3.33333333333333 c = 10; b = c / 3; cell(4,1) = b; ← 3.33333333333333 a = 1 + 2 + 3; ← 6 cell(5,1) = a; a = 4 * 5 + 3 * 2; cell(6,1) = a; ← 26 a = 4 * (5 + 3); cell(7,1) = a; ← 32 a = cell(3,4); ←3行目、4列目が空の場合はaは0扱い |
記号 | 内容 |
---|---|
+ | 加算 |
- | 減算 |
* | 乗算 |
/ | 除算(0で割ると0扱いされます。ただし今後エラーにするかも?) |
% | 余り(0で割ると0扱いされます。ただし今後エラーにするかも?) |
例にあるように一般的な四則演算が可能です。
乗算、除算が優先が高く加算、減算でも括弧で囲むことで優先順位を
上げることが可能です。
ただし、型により小数点の扱い方には注意ください。
string test(int row, int col) // <= 関数 { int str; str = cell(row, col); str = union("""", str, """"); return str; } // 関数の呼び出し msg(test(5,6)); // 5行目、6列目のセルの内容に // ダブルコーテーションを囲んで // メッセージを表示する |
【関数の指定方法】
以下の4つの処理で構成された命令が関数となり、以降の処理で呼び出す
ことが可能です。
・戻り値の変数型定義 : 関数の戻り値の変数の型を定義します。
値を返さない場合はvoidを指定します。
sheetの指定は出来ません。
・関数名 : 任意の名称(単語と認識できる文字列)
半角の括弧やスペースなどシステム文字が入ると単語と認識がなくなります。
名前が重複する場合はエラーとなります。
・"(" 引数 ")" : 変数型と変数名の引数を最大5個まで指定出来ます。
・以降大括弧で囲んだ処理
【備考】
・呼び出すより前に関数を記述(C言語的だがプロトタイプ宣言はありません。)
・引数の値は常に値渡しとなるのでレスポンスを求めるならグローバル変数的で値を渡すほうが良い。
#include "calender" // calender.hshファイルに記述された関数を呼び出す listSyuku("2021", get_cur_row(), get_cur_col()); |
【内容】
よく使う関数をマクロごとにコピーして利用するのは対象の関数に修正が発生したとき
コピーしたファイル全てに対して修正を入れる必要があるのでメンテナンスの観点
で良くありません。
そこでインクルードファイルに関数を用意しておけば修正するファイルは
1つで全ての処理に修正内容が反映されます。
注意点としてはincludeファイルから呼び出された関数の中でエラーが発生したとき
エラーの行番号はincludeファイルを呼び出した行になるため
エラーに対するメンテナンスは難しくなるのでエラーが出なくなってから
includeファイルで扱うことをおすすめします。
【#includeの指定方法】
#includeの命令の後にファイル名を指定します。
・ファイル名の前後にダブルコーテーションで囲む必要があります。
・ファイルはソースファイルと同じフォルダにあるファイルを参照します。(ver4.0以降)
ファイルが見つからない場合は実行ファイルを置いたフォルダのmacroフォルダにある
ファイルを参照します。
・拡張子を指定しない場合は「.hsh」となります。
・ファイル名は30文字まで。
・#includeの指定は他の命令とは違ってスペースを空けずに左に詰めて記述してください。
・命令の最後にセミコロンは不要です。
・includeファイルの中に#includeの指定は出来ません。
厳密には配列は存在しません。
代わりに配列的に扱う関数を用意しています。
整数型を扱うarray(index)、文字列型を扱うarray_str(index)です。
配列とは違いますがarray_word()というプログラム的な意味での単語単位を作者の
独自の解釈をもとに分類して配列的に扱うようにしたものを用意しています。
使用する前に領域を確保する必要があります。
create_array(100);とするとarray(0)からarray(99)までの配列が使用可能となります。
array_str()も同様にcreate_array_str(100)でarray_str(0)からarray_str(99)までに
文字列が設定出来ます。
array_str()はarray()と違って第2引数にAS0(0)からAS4(4)を指定することで
複数のarray_str()を使用することができるようになります。第2引数を省略するとAS0(0)と
同じ意味となります。
第2引数に指定するAS0〜AS4は0〜4の定数で数字を指定してもいいですが
数字だと2次元配列のように見えるのでここではAS0とかの定数を使用する
ようにします。
// 整数の扱い方 int nLp; create_array(100); nLp = 0; while(nLp < 100) { // array()を使う意味は無いですが使い方 array(nLp) = nLp; cell(nLp + 1,1) = array(nLp); nLp = nLp + 1; } -- 結果 ---------------------- 0 1 2 : 98 99 |
int nRow; create_array_str(10); array_str(0) = "りんご"; array_str(1) = "みかん"; array_str(2) = "柿"; nRow = 1; while(nRow < 100) { cell(nRow,1) = array_str(get_random(3)); nRow = nRow + 1; } -- 結果(ランダムなので何が配置されるかは変わります)---- 柿 みかん みかん りんご 柿 りんご : みかん |
int nIndex; create_array_str(10, AS0); array_str(0, AS0) = "りんご"; array_str(1, AS0) = "みかん"; array_str(2, AS0) = "柿"; create_array_str(10, AS1); array_str(0, AS1) = "\200円"; array_str(1, AS1) = "\500円"; array_str(2, AS1) = "\300円"; nIndex = select_array_str("果物", "選択下さい。",AS0); if(nIndex < 0){ quit(); } cell(1,1) = array_str(nIndex, AS1); -- 結果 --------------------------- 選択画面が出て「柿」を選択すると 1行目の1列目に「\300円」を設定 |
現在開いているシートを指定する。
sheet st; st = get_sheet_name(get_sel_sheet_idx()); // st = ""; // シート名なしは指定できない |