[[20230301183714]] 『記入関数を一覧表のように表示する』(マサイ) ページの最後に飛ぶ

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

 

『記入関数を一覧表のように表示する』(マサイ)

シート内に記入した全ての関数式を別シートに
どこのセルで
どんな関数式が使われたか
一覧表示する方法(VBA)はありますか?

例えば、sheet1が下記の場合

    |[A]        |[B]     |[C]
 [2]|     123456|=LEN(A2)|   
 [3]|        789|=LEN(A3)|   
 [4]|       2562|=LEN(A4)|   
 [5]|=SUM(A2:A4)|        |   

sheet2に以下のように書き出す

     |[A]|[B]       
 [1]|B2  |=LEN(A2)   
 [2]|B3  |=LEN(A3)   
 [3]|B4  |=LEN(A4)   
 [4]|A5  |=SUM(A2:A4)

書き出す型式は、他に分かりやす型式があれば
上記にはこだわりはありません。

< 使用 Excel:Microsoft365、使用 OS:Windows11 >


 Sub test()
     Dim ws1 As Worksheet, ws2 As Worksheet
     Dim rng As Range, i As Long
     Set ws1 = Worksheets("Sheet1")
     Set ws2 = Worksheets("Sheet2")
     For Each rng In ws1.Range("A1").CurrentRegion
         If rng.HasFormula Then
             i = i + 1
             ws2.Cells(i, "A") = rng.Address(0, 0)
             ws2.Cells(i, "B") = "'" & rng.Formula
         End If
     Next
 End Sub
(フォーキー) 2023/03/01(水) 19:00:41

フォーキーさん、コードありがとうございます。

CurrentRegionでA1の塊を候補にしていますが
他にも塊でない場所にも関数を書いたセルがあります。

アクティブシート内の使用中の全てのセルを対象にしたいので
以下を考えましたがエラーは出ませんが上手くいきません。

どう変更すれば良いですか?

 Sub 関数一覧()
     Dim ws2 As Worksheet
     Dim i As Long

     Set ws2 = Worksheets("Sheet2")

     With ActiveSheet.UsedRange
         If .HasFormula Then
             i = i + 1
             ws2.Cells(i, "A") = rng.Address(0, 0)
             ws2.Cells(i, "B") = "'" & rng.Formula
         End If
     End With
 End Sub

(マサイ) 2023/03/02(木) 08:10:26


思いつきで試したら上手く処理されました。

Option Explicit

Sub 関数一覧()

    Dim ws2 As Worksheet, Asht As Worksheet
    Dim rng As Range, i As Long

    Set ws2 = Worksheets("Sheet2")
    Set Asht = ActiveSheet

    For Each rng In Asht.UsedRange
        If rng.HasFormula Then
            i = i + 1
            ws2.Cells(i, "A") = rng.Address(0, 0)
            ws2.Cells(i, "B") = "'" & rng.Formula
        End If
    Next
End Sub

できたらB列のセルがどんな数式なのかを説明したセルが周囲にあるのですが
これをC列に書き込みたいと思いますが何か方法がありますか?

例えば

k12 : 時間4

      |[A]|[L]         |[C] 
 [12] |K7 |=HOUR(J5)  |時間4

 問題なのは、説明したセルが数式の周囲にあるので
 以下の場合では、8つの内どれを指定するかを手動で選択すると言うことです。
 (上の場合は、左側の「時間4」を選択)

     |[K]   |[L]      |[M]   
 [11]|時間1|時間2   |時間3
 [12]|時間4|=HOUR(J5)|時間5
 [13]|時間6|時間7   |時間8

(マサイ) 2023/03/02(木) 08:39:03


γさん、アドバイス感謝します。

CtrlとShiftキーを押しながら@キーで式モードになる。
なるほど便利な機能ですね。

式モードは、それはそれで便利なのですが
やはり一覧表は、捨てがたいです。

08:10:26で提案した一覧表(説明付き)を完成させたいと思います。
何か、方法があればお願いします。
(マサイ) 2023/03/02(木) 08:48:44


Sub 関数一覧()
    Dim Asht As Worksheet, Resultws As Worksheet
    Dim rng As Range, i As Long
    Dim TargetCells As Long
    Set Asht = ActiveSheet
    Set Resultws = ThisWorkbook.Worksheets("Sheet2")

    On Error GoTo ErrHandl
    TargetCells = Asht.Cells.SpecialCells(xlCellTypeFormulas, 23).Count
    On Error GoTo 0

    Resultws.Range("A1").CurrentRegion.Clear

    Application.DisplayAlerts = False

    On Error GoTo nextloop
    ReDim PasteArr(1 To TargetCells, 1 To 3)
    For Each rng In Asht.Cells.SpecialCells(xlCellTypeFormulas, 23)
        i = i + 1
        PasteArr(i, 1) = rng.Address(0, 0)
        PasteArr(i, 2) = "'" & rng.Formula
        Asht.Activate
        rng.Select
        PasteArr(i, 3) = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください", Type:=8).Value
nextloop:
    Err.Clear
    Next
    On Error GoTo 0

    Application.DisplayAlerts = True

    Resultws.Range("A1", Resultws.Cells(TargetCells, 3)) = PasteArr
    Exit Sub

ErrHandl:

    MsgBox ("数式は見つかりませんでした。")
    Err.Clear
End Sub
(cZnc2hu00T) 2023/03/02(木) 10:58:12

cZnc2hu00Tさん、参加いただきありがとうございます。

早速コードを試してみました。
思い描いていた手順で説明が設定できるので何点かは除いて完璧です。

試用したシートに結合セルがあるので何箇所か
B列が空欄のセルができました。
これは、後でB列が空欄のセルは、行を削除すれば問題ないと思います。

構想が甘く月ごとの集計のようなシート構成では、
同じ列に縦長に日付が日数分ある場合、計算式も同じ数だけ配置される場合は何度も同じ説明を選択する事です。
そこでVBAで行が更新されて同じ列が出た場合に、
例えば「F列は、2度めですが同じ説明ですか?」と聞くようにして
「Y」でF列の説明を最初の説明と同じとして以後問い合わせをしないようにコードを変更したいのですができますか ?

(マサイ) 2023/03/02(木) 12:29:20


Sub 関数一覧()
    Dim Overlapcheck As Object
    Dim OverlapOK As Object
    Set Overlapcheck = CreateObject("Scripting.Dictionary")
    Set OverlapOK = CreateObject("Scripting.Dictionary")

    Dim Asht As Worksheet, Resultws As Worksheet
    Dim rng As Range, i As Long
    Dim TargetCells As Long
    Set Asht = ActiveSheet
    Set Resultws = ThisWorkbook.Worksheets("Result")

    On Error GoTo ErrHandl
    TargetCells = Asht.Cells.SpecialCells(xlCellTypeFormulas, 23).Count
    On Error GoTo 0

    Resultws.Range("A1").CurrentRegion.Clear

    Application.DisplayAlerts = False

    ReDim PasteArr(1 To TargetCells, 1 To 3)
    For Each rng In Asht.Cells.SpecialCells(xlCellTypeFormulas, 23)
        If (rng.Formula <> "") Then
            i = i + 1
            PasteArr(i, 1) = rng.Address(0, 0)
            PasteArr(i, 2) = "'" & rng.Formula
            PasteArr(i, 3) = Explain(Overlapcheck, OverlapOK, Asht, rng)
        End If
    Next
    On Error GoTo 0

    Application.DisplayAlerts = True

    Resultws.Range("A1", Resultws.Cells(TargetCells, 3)) = PasteArr
    Exit Sub

ErrHandl:

    MsgBox ("数式は見つかりませんでした。")
    Err.Clear
End Sub

Function Explain(ByRef Overlapcheck As Object, ByRef OverlapOK As Object, ByRef Asht As Worksheet, ByRef rng As Range) As String

    Dim CheckColumn
    CheckColumn = Split(rng.Address, "$")(1)

    On Error GoTo nextloop
    If Overlapcheck.exists(CheckColumn) Then
        If (OverlapOK.exists(CheckColumn)) Then
            Explain = Overlapcheck.Item(CheckColumn)
        Else
            If (MsgBox(CheckColumn & "列は前に" & Overlapcheck.Item(CheckColumn) & _
                "と入力されていますが、以降同じ説明ですか?", vbYesNo) = vbYes) Then
                OverlapOK.Add Item:=True, Key:=CheckColumn
                Explain = Overlapcheck.Item(CheckColumn)
            Else
                Asht.Activate
                rng.Select
                Explain = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください", Type:=8).Value
                Overlapcheck.Remove CheckColumn
                Overlapcheck.Add Item:=Explain, Key:=CheckColumn
            End If
        End If
    Else
        Asht.Activate
        rng.Select
        Explain = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください", Type:=8).Value
        Overlapcheck.Add Item:=Explain, Key:=CheckColumn
    End If
    On Error GoTo 0

    Exit Function

nextloop:

    Err.Clear
End Function

(cZnc2hu00T) 2023/03/02(木) 14:06:58


同じ説明を加味した修正コードありがとうございます。
結合セルの処理も追加いただきバッチリ結果がでるようになりました。

大満足で結果を書き出すシートを「関数一覧」として
「関数一覧」シートの有無でシートを作成するか/しないかを判断するコードを追加しましたが
どうもActiveSheetを設定するコードに不備があるようで上手く書き出されません。

又、途中で以下のコードで「インデックスが有効範囲にありません。」のエラーがでました。
PasteArr(i, 1) = rng.Address(0, 0)

すいませんが、コードを見ていただけませんか?

Option Explicit

Sub 関数一覧3()

    Dim Overlapcheck As Object
    Dim OverlapOK As Object
    Set Overlapcheck = CreateObject("Scripting.Dictionary")
    Set OverlapOK = CreateObject("Scripting.Dictionary")
    Dim Asht As Worksheet, Resultws As Worksheet, temp As Worksheet
    Dim rng As Range, i As Long
    Dim TargetCells As Long
    Dim flg As Long

    Set Asht = ActiveSheet

    '関数一覧シートの存在チェック
    For i = 1 To Sheets.Count
        If Sheets(i).Name = "関数一覧" Then
            flg = 1
        End If
    Next

    If flg <> 1 Then
        Set temp = Sheets.Add(after:=Sheets(Sheets.Count))
        temp.Name = "関数一覧"
    End If

    Asht.Activate
    Set Resultws = Worksheets("関数一覧")

    On Error GoTo ErrHandl
    'データの種別が数式、文字、論理値、エラー値であるセルをカウント
    TargetCells = Asht.Cells.SpecialCells(xlCellTypeFormulas, 23).Count

    On Error GoTo 0
    '書き出しシート初期化(クリアー)
    Resultws.Range("A1").CurrentRegion.Clear

    Application.DisplayAlerts = False

    ReDim PasteArr(1 To TargetCells, 1 To 3)

    For Each rng In Asht.Cells.SpecialCells(xlCellTypeFormulas, 23)
        If (rng.Formula <> "") Then
            i = i + 1
            PasteArr(i, 1) = rng.Address(0, 0)
            PasteArr(i, 2) = "'" & rng.Formula

            '独自関数(説明記入)
            PasteArr(i, 3) = Explain(Overlapcheck, OverlapOK, Asht, rng)
        End If
    Next

    On Error GoTo 0  'エラー処理を無効にする
    Application.DisplayAlerts = True
    Resultws.Range("A1", Resultws.Cells(TargetCells, 3)) = PasteArr
    Exit Sub

ErrHandl:

    MsgBox ("数式は見つかりませんでした。")
    Err.Clear
End Sub
Function Explain(ByRef Overlapcheck As Object, ByRef OverlapOK As Object, ByRef Asht As Worksheet, ByRef rng As Range) As String
    Dim CheckColumn

    CheckColumn = Split(rng.Address, "$")(1)

    On Error GoTo nextloop
    If Overlapcheck.exists(CheckColumn) Then
        If (OverlapOK.exists(CheckColumn)) Then
            Explain = Overlapcheck.Item(CheckColumn)
        Else
            If (MsgBox(CheckColumn & "列は前に" & Overlapcheck.Item(CheckColumn) & _
                "と入力されていますが、以降同じ説明で良いですか ?", vbYesNo) = vbYes) Then
                OverlapOK.Add Item:=True, Key:=CheckColumn
                Explain = Overlapcheck.Item(CheckColumn)
            Else
                Asht.Activate
                rng.Select
                Explain = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください。", Type:=8).Value
                Overlapcheck.Remove CheckColumn
                Overlapcheck.Add Item:=Explain, Key:=CheckColumn
            End If
        End If
    Else
        Asht.Activate
        rng.Select
        Explain = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください。", Type:=8).Value
        Overlapcheck.Add Item:=Explain, Key:=CheckColumn
    End If

    On Error GoTo 0
    Exit Function
nextloop:
    Err.Clear

End Function

(マサイ) 2023/03/02(木) 17:21:15


変更点
変数tempの役割がResultwsと被っていたため統合(最後にResultwsに書き出しているのでどのみち正常に動かないです)
変数flgの名前をわかりやすく変更
変数iが二ヶ所で使われてしまっていたため片方の名前を変更(これが"インデックスが有効範囲にありません。"というエラーが出た原因)

Sub 関数一覧3()

    Dim Overlapcheck As Object
    Dim OverlapOK As Object
    Set Overlapcheck = CreateObject("Scripting.Dictionary")
    Set OverlapOK = CreateObject("Scripting.Dictionary")
    Dim Asht As Worksheet, Resultws As Worksheet
    Dim rng As Range, i As Long, inArr As Long
    Dim ResultwsCheck As Boolean
    Dim TargetCells As Long
    Set Asht = ActiveSheet
    '関数一覧シートの存在チェック
    ResultwsCheck = False
    For i = 1 To Sheets.Count
        If Sheets(i).Name = "関数一覧" Then
            ResultwsCheck = True
            Set Resultws = Worksheets("関数一覧")
        End If
    Next
    If Not ResultwsCheck Then
        Set Resultws = Sheets.Add(after:=Sheets(Sheets.Count))
        Resultws.Name = "関数一覧"
    End If
    Asht.Activate
    On Error GoTo ErrHandl
    'データの種別が数式、文字、論理値、エラー値であるセルをカウント
    TargetCells = Asht.Cells.SpecialCells(xlCellTypeFormulas, 23).Count
    On Error GoTo 0
    '書き出しシート初期化(クリアー)
    Resultws.Range("A1").CurrentRegion.Clear
    Application.DisplayAlerts = False
    ReDim PasteArr(1 To TargetCells, 1 To 3)
    For Each rng In Asht.Cells.SpecialCells(xlCellTypeFormulas, 23)
        If (rng.Formula <> "") Then
            inArr = inArr + 1
            PasteArr(inArr, 1) = rng.Address(0, 0)
            PasteArr(inArr, 2) = "'" & rng.Formula
            '独自関数(説明記入)
            PasteArr(inArr, 3) = Explain(Overlapcheck, OverlapOK, Asht, rng)
        End If
    Next
    On Error GoTo 0  'エラー処理を無効にする
    Application.DisplayAlerts = True
    Resultws.Range("A1", Resultws.Cells(TargetCells, 3)) = PasteArr
    Exit Sub
ErrHandl:
    MsgBox ("数式は見つかりませんでした。")
    Err.Clear
End Sub
Function Explain(ByRef Overlapcheck As Object, ByRef OverlapOK As Object, ByRef Asht As Worksheet, ByRef rng As Range) As String
    Dim CheckColumn
    CheckColumn = Split(rng.Address, "$")(1)
    On Error GoTo nextloop
    If Overlapcheck.exists(CheckColumn) Then
        If (OverlapOK.exists(CheckColumn)) Then
            Explain = Overlapcheck.Item(CheckColumn)
        Else
            If (MsgBox(CheckColumn & "列は前に" & Overlapcheck.Item(CheckColumn) & _
                "と入力されていますが、以降同じ説明で良いですか ?", vbYesNo) = vbYes) Then
                OverlapOK.Add Item:=True, Key:=CheckColumn
                Explain = Overlapcheck.Item(CheckColumn)
            Else
                Asht.Activate
                rng.Select
                Explain = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください。", Type:=8).Value
                Overlapcheck.Remove CheckColumn
                Overlapcheck.Add Item:=Explain, Key:=CheckColumn
            End If
        End If
    Else
        Asht.Activate
        rng.Select
        Explain = Application.InputBox(prompt:=rng.Address(0, 0) & "の説明を選択してください。", Type:=8).Value
        Overlapcheck.Add Item:=Explain, Key:=CheckColumn
    End If
    On Error GoTo 0
    Exit Function
nextloop:
    Err.Clear
End Function
(cZnc2hu00T) 2023/03/03(金) 08:24:06

cZnc2hu00Tさん、昨日に続きコードの修正ありがとうございます。

エラー「インデックスが有効範囲にありません。」についてですが

シートの構成を少しずつ替えて数パターンでマクロを試してみた結果
エラーが出るのは、同じ列で既に説明を記入したセルがあって更に
同列で途中に何も記入されていない空白のセルがあるに場合に発生していました。

昨日から変数(i)の使い回しが原因とは、思いもよらず
全く違うところに着目して泥沼に入り込んで悪戦苦闘していました。

まだ、数パターンしか試していませんが教えてもらったコードで上手く処理されています。

アドバイス感謝いたします。

(マサイ) 2023/03/03(金) 10:18:04


最後に下記処理を追加してこれで一応完成と思います。

関数一覧.Range("A1").CurrentRegion.Sort key1:=関数一覧.Range("A1"), Order1:=xlAscending
(マサイ) 2023/03/03(金) 10:49:13


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.