[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『『SUB()の位置の入れ替え』 その2』(kenN)
以前sub()の位置をソートする以下のマクロを教えてもらいました。
『SUB()の位置の入れ替え』 https://www.excel.studio-kazu.jp/kw/20211121183345.html
その後、丸数字の各マクロを呼び出すマクロ「ALL_****()」がソートすると
一番下に来るので、ソート後にTOPに来るように手動で位置を調整する事が必要です。
せっかくなら、最後の手動並び替えをせずに呼び出しマクロ「ALL_****()」が
トップに来るようにコードを改造したいのですがどこを修正すれば良いですか ?
以下がソート後の希望の順番です。
sub all_*****() sub 1test() sub 2test() sub 3test() sub 4test() sub 5test() 上記の「sub 」の後の数字は実際は、丸数字(機種依存文字)です。
それと、個人的にはこのマクロをアドインに組み込めば
利便性が向上すると思っているのですが改造できますか?
(現在は、ソートコードをソートするコードにコピペして
ソート後に削除する行為を繰り返しています。)
アドインでは無く、他の方法でも利便性が向上するなら手段は問いません。
Sub サブの位置の入れ替え()
Dim sortedlist As Object Dim k& Dim num&, declarationCodes$ Dim codes$ Dim procname$ Dim startline&, numOfLines& Dim sortedCodes$
Set sortedlist = CreateObject("System.Collections.SortedList") 'key => valueのペアを管理するが、keyを自動的にソートする点が特徴。 '.Netのツールを援用 '"プロシージャ名"と"プロシージャごとのコード文字列"を取得 With ThisWorkbook.VBProject.VBComponents("Module1").CodeModule
'宣言部分のコードを取得 num = .CountOfDeclarationLines declarationCodes = .Lines(1, num)
'各プロシージャのコードを取得 For k = 1 To .CountOfLines If procname <> .ProcOfLine(k, 0) Then procname = .ProcOfLine(k, 0) startline = .ProcStartLine(procname, 0) numOfLines = .ProcCountLines(procname, 0) codes = .Lines(startline, numOfLines) sortedlist.Add procname, codes End If Next
'keyの昇順でコード文字列を連結 For k = 0 To sortedlist.Count - 1 sortedCodes = sortedCodes & sortedlist.getByIndex(k) & vbLf Next
'いったんすべてを消去して If .CountOfLines > 0 Then Call .DeleteLines(1, .CountOfLines) End If
'ソート済みのコードを書き込む .AddFromString declarationCodes .AddFromString sortedCodes End With End Sub
< 使用 Excel:Office365、使用 OS:Windows10 >
とすると自動でリンクにしてくれる。 (ねむねむ) 2021/11/26(金) 14:27
マクロ組めるスキルがあるのなら、
調べる、読み解くスキルも身に付けると
幅が広がりますよ。
(tkit) 2021/11/26(金) 15:24
tkitさんの回答のアイデアそのものですが、下記のような感じでしょうか。
For k = 1 To .CountOfLines If procname <> .ProcOfLine(k, 0) Then procname = .ProcOfLine(k, 0) '以下のIf分を追加 If procname Like "all_*" Then procname = "0" & procname End If startline = .ProcStartLine(procname, 0) numOfLines = .ProcCountLines(procname, 0) codes = .Lines(startline, numOfLines) sortedlist.Add procname, codes End If Next (hatena) 2021/11/26(金) 16:55
指定された下記コードを指定位置に追加して試してみました。
'以下のIf分を追加 If procname Like "all_In_One" Then procname = "0" & procname End If
("all_*は、all_In_Oneとしています。)
そうすると、下記でエラーで出ました。
startline = .ProcStartLine(procname, 0)
実行エラー 35 SUBまたはFunctionが定義されていません。
エラーが出る前のprocnameは、"0ALL_In_On"です。
(”0”&procnameの為、0が付加された形式)
情報不足でしょうが、エラーの原因が何か分かりますか?
(kenN) 2021/11/26(金) 18:43
# 散歩から戻りました。結構、暮れるのが早いですね。
文字列変数pnameを追加して、 If procname Like "all_*" Then pname = "0" & procname Else pname = procname End If sortedlist.Add pname, codes のようにSortedListのキーだけを変更したほうがよいと思いました。
【余談】 そういえば、大昔、とある掲示板で、コードを一括して修正するコードを提案したところ、 「それは、マクロウイルス作成を助長するから」と、投稿を削除させられたことがある。 そういう思考を持つ人にはとても簡単な話で、そんなことが抑止効果を持つとは 思えないし、ウイルスのやっかないところはもっと別のところにあるはずで、 心の底から削除に賛成はできなかったが、前例があるのでと言われ、争うこともないかなと 大勢に従った記憶がある。 でも今では、著名なt.tanaka氏(パソ通時代のHN)のサイトにコードが公開されているから、 それを参照してくださいというだけで済み、昔のことのようなことはない。
ただ昨今は、退職に伴って、ワークシートの計算式をすべて値にして、実質使えないようにしたい、 などという人も現れる時代だから、昔のひとの考え方も一理あるのかなどと再考することもあります。 こうしたテーマ(コードでコードを修正する)は微妙なところがあるので、 原則は自己責任のように思います。 同様に、自分の持っているスキルの範囲内で工夫していただくのが基本でしょう。 (γ) 2021/11/26(金) 19:03
If文の挿入位置が間違ってました。
sortedlist.Add procname, codes
の直前に移動させてください。 (hatena) 2021/11/26(金) 20:01
にあるSample14(すべてのプロシージャ名を取得する例) を安直に下敷きにしてしまいました。 これだと、一行ごとに処理していくので効率が悪いし、 procnameを使って新しいプロシージャ名の判定をするという、 hatenaさんのようなかたにも想像しにくいコードになっていたものを思います。 (2021/11/26(金) 20:01のご指摘にもかかわらず、エラーになります。)
そこで、少し見直してみました。このほうがたぶん効率もよいでしょう。
Sub サブの位置の入れ替え2() Dim sortedlist As Object Dim k&, num& Dim declarationCodes$, codes$ Dim procname$, pname$ Dim startline&, numOfLines& Dim sortedCodes$
Set sortedlist = CreateObject("System.Collections.SortedList")
With ThisWorkbook.VBProject.VBComponents("Module1").CodeModule '宣言部分のコードを取得 num = .CountOfDeclarationLines declarationCodes = .Lines(1, num)
'各プロシージャのコードを取得 k = num + 1 Do While k <= .CountOfLines procname = .ProcOfLine(k, 0) startline = .ProcStartLine(procname, 0) numOfLines = .ProcCountLines(procname, 0) codes = .Lines(startline, numOfLines) If procname Like "all_*" Then pname = "0" & procname Else pname = procname End If sortedlist.Add pname, codes k = k + numOfLines Loop
'keyの昇順でコード文字列を連結 For k = 0 To sortedlist.Count - 1 sortedCodes = sortedCodes & sortedlist.getByIndex(k) & vbLf Next sortedCodes = Left(sortedCodes, Len(sortedCodes) - 1) 'ここも修正
'いったんすべてを消去して If .CountOfLines > 0 Then Call .DeleteLines(1, .CountOfLines) End If 'ソート済みのコードを書き込む .AddFromString declarationCodes .AddFromString sortedCodes End With End Sub
この読み飛ばし方式にすれば、上記のようにpnameを導入しなくても、指摘どおりで動作します。
(γ) 2021/11/26(金) 23:42
2021/11/26(金) 19:03 2021/11/26(金) 23:42
おかげさまで修正コードで上手く処理できました。
素人が(コードでコードを修正する)ような行為は危ない事でしょうが
コードを後で見直す場合などコードは、
時系列で順番に並んでいた方が何かと便利なので相談させていただきました。
自己責任の範疇での運用に限定します。
(hatena)さん、エラーの修正コードありがとうございます。
(γ)さんによると修正コードでもエラーが出るとの事なので
コード自体は試していません。
(kenN) 2021/11/27(土) 06:41
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.