[[20211126141727]] 『『SUB()の位置の入れ替え』 その2』(kenN) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『『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 >


[[20211121183345]]

 とすると自動でリンクにしてくれる。
(ねむねむ) 2021/11/26(金) 14:27

'各プロシージャのコードを取得 時
ALL何某があったらKeyに0でも入れればいいんじゃないですかね。

マクロ組めるスキルがあるのなら、
調べる、読み解くスキルも身に付けると
幅が広がりますよ。
(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

hatenaさん、回答感謝します。

指定された下記コードを指定位置に追加して試してみました。

    '以下の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

http://officetanaka.net/excel/vba/vbe/05.htm
 にある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.