○第43回目 ちょっと寄道の2
前回説明したように、エクセルマクロから命令等不要な部分を削除します。
そこから、変数を抜き出すというマクロです。
変数は、
半角スペース+変数名+半角スペース+変数名+半角スペース…、となっていて変数名の数はわかりませんが、最後は半角スペースで終わっています。
一部を取り出すと次のようになっています(末尾の半角スペースが削除されています。自動設定をしているために、保存すると末尾スペースが削除されてしまうからです)。
AAA
p1 (AAA )
AAA1 (AAA p1 1)
retu1 (AAA1)
gyo1 (AAA1)
AAA9 (AAA p1 1)
retu9 (AAA9)
gyo9 (AAA9)
gyo_cnt gyo9 gyo1 1
retu_cnt retu9 retu1 1
k 0 1
i 0 gyo_cnt 1
dd1(i) (gyo1 i retu1 k)
dd2(i) i
i
i 0 gyo_cnt 2
j i 1 gyo_cnt 1
dd1(j) dd1(i)
AA dd1(j)
dd1(j) dd1(i)
dd1(i) AA
bb dd2(j)
dd2(j) dd2(i)
dd2(i) bb
:
これから、
Dim AA,AAA,AAA1,AAA9,bb
Dim dd1(100),dd2(100),dd3(100),gyo1,gyo9
Dim gyo_cnt,i,j,k,n_gen(100)
Dim n_new(100),n_old(100),p1,retu1,retu9
Dim retu_cnt,
というものを抜き出すのです。配列定義の(100)は、一意的に(100)にしているものです。
ソートをかけていますので、配列変数と通常の変数が混在しています。
マクロを見て行きます。
全文対象なので、一行目から最後まで同じことを繰り返します。
最初の段階では重複は削除しません。
変数名はスペースに区切られていますので、半角スペースを探していきます。二回探して始まりと終わりの位置をとります。
変数名を取り終わったら、配列変数に格納して、格納した変数までを削除したもの(スペースは残す)で同じように探していきます。スペースが二つなければその行は終了です。
これを最終行まで繰り返しますが、問題は変数名ではないものまでが入っているということです。一例を挙げれば、数値です。あとは、変数ではあるが、外の場所に記述されているもの、カッコ内のものの一部です。
i 0 gyo_cnt 2 ←"0","2"は数値
p1 (AAA) ←"(AAA)"はほかの場所で必ず出てくるもの
AAA1 (AAA p1 1) ←"(AAA"、"1)"はカッコ内の一部。
← "p1"はカッコ内の一部ですが、その判断ができないので、生かされます。
dd2(i) i ← "dd2(i)"は配列変数なので、カッコ内を100にします。
取得した変数名をソートし、重複部分を除きます。
そして、五こずつ、Dimに続けて表示します。
流れはこんなものです。
具体的に見てみましょう。(これはQXマクロです)
'初めのおまじない
if @hwnd = 0 then exit proc
'選択範囲を記憶
y_begin = @SelectStartLine 'これは物理的行数
y_end = @ScrLineToCrLine(@SelectEndLine) 'これは論理的行数
@BlockSelectEnd
if y_begin = 0 then
y_begin = 1 'これは物理的行数
y_end = @ScrLineToCrLine(@LastLine) 'これは論理的行数
end if
'メイン処理
'指定された範囲の中における、変数を持つ文字列を抜き出す。
'形式は、半角スペース+変数十半角スペースとなっている
@Line = y_begin
i= 0
do =⇒このdoは指定範囲内で繰り返すという意味のもの
a$ = @textCr$(@Line) =⇒一行の内容を変数に入れる
b$ = a$
do while 1 =⇒一行の中から変数名を抜き出す。変数名の数がわからないので、無限ループになっている。
rr$ = " "
p1 = instr(b$,rr$) =⇒rr$は半角スペースのこと。一つ目のスペースの位置取得
p2 = instr(mid$(b$,p1+1),rr$) =⇒二つ目のスペースの一取得。p2は最初のスペースは除いた位置である。変数名の長さ+1となる
if p2 = 0 then exit do '抜け出る
c$= left$(mid$(b$,p1+1,p2-1),1) =⇒抜き出した変数名候補の先頭の文字を取得
d$= right$(mid$(b$,p1+1,p2-1),1) =⇒抜き出した変数名候補の最後の文字を取得
if c$ < "0" or c$ > "9" then ' 0<= c$ <=9 は除外 =⇒数値は除く
if c$ <> "(" then 'c$ = ( は除外 =⇒"("で始まっているものは除く
p3 = instr(mid$(b$,p1+1,p2-1),"(")
if p3 = 0 or d$ = ")" then '途中に( があり、かつ、末尾が ) でない は除外
if p3 <> 0 or d$ <> ")" then '途中に( がなく、かつ、末尾が ) である は除外
if p3 <> 0 and d$ = ")" then '途中に( がある、かつ、末尾が ) である
mm1$[i] = left$(mid$(b$,p1+1,p2-1),p3) & "100)" =⇒配列変数なので、配列数を一意的に100とする。
i = i + 1
else '途中に( がなく、または、末尾が ) でない
mm1$[i] = mid$(b$,p1+1,p2-1)
i = i + 1
end if
end if
end if
end if
end if
b$ = mid$(b$,p2)
loop
@MoveNextLineCr '改行し次の行へ
loop while @ScrLineToCrLine(@Line) < y_end
m_end = i-1 '定数の個数(0を含める)
if m_end = 0 then exit proc
'ソート
for i = 0 to m_end-1 'ソート
min$=mm1$[i]
for j = i+1 to m_end
if min$ > mm1$[j] then
min$ = mm1$[j]
mm1$[j] = mm1$[i]
mm1$[i] = min$
end if
next
next
'重複した場合クリアする
for i = 0 to m_end-1
for j = i+1 to m_end
if mm1$[i] <> mm1$[j] then exit for
mm1$[j] = ""
next
next
'重複の削除。つめる。
j = 0
for i = 0 to m_end
if mm1$[i] <> "" then
mm1$[i-j] = mm1$[i]
else
j=j+1
end if
next
m_end2 = m_end - j '最終的な定数の数
'末尾に追加。五単位で改行。間はカンマで区切る
@InsertF "\n" =⇒改行命令
@InsertF "\n"
i=0
@Insert "Dim "
for m= 0 to m_end2
i=i+1
if i= ll005 then
@Insert mm1$[m]
@InsertF "\n"
@Insert "Dim "
i=0
else
@Insert mm1$[m]
@Insert ","
end if
next
@InsertF "\n"
@InsertF "\n"
※これはQXマクロである。
※今後の改修点
・QXマクロプログラムでも変数を抜き出せるようにする。(削除表(変換表)の作りで終了)
・変数の種類別に、変数名を分類し、その順番に出力する。配列変数、文字用変数、その他の分類
・その他の更なる分類。一文字のもの、二文字のもの、間に"_"があるもの、その他
こんなところを改善点として考えています。
次回から本道に戻ります。

0 件のコメント:
コメントを投稿