Forum Discussion

burnskrl's avatar
burnskrl
Copper Contributor
Feb 06, 2025

Adding existing VBA/Macro in Private Function to new Workbook

 

Hello again!

I have inherited a workbook with a Macro that stores qualitative notes in a separate worksheet and compiles the notes over time. I want to take that Macro and apply it to a new workbook and use the functionality for the same purpose. When I move the Macro into my new workbook, it doesn't come up as an executable process - that is, it doesn't show up in my list of Macros to run.  (See below image)

 

 

 

 

 

 

 

 

 

 

 

I am new to Macros and still learning, but is there some way to get this Macro to run in my new workbook? 

 

This is the first part of the Macro which checks the setup of the in use workbook and makes adjustments accordingly. 

Anytime I've created my own Macro, it starts with the 'Sub' header. I have other Macros in this VBA that begin with 'Sub' and they show up in the list of Macros to run. In this Macro, however, it starts with 'Option Explicit' and then 'Public Function'. There are also parts of the full Macro that begin with 'Private Function'. My thought was to make these available to any workbook that I create, but since they aren't showing up on my Macro list, I can't make the adjustment to have them exist in any workbook. 

 

VBA:

Option Explicit
Public Const sRngName = "PT_Notes"
 
Public Function Check_Setup(ws As Worksheet) As Boolean
    Dim rNotes As Range, i As Long
    Dim PT As PivotTable, ptField As PivotField
    Dim tblNotes As ListObject
    Dim wsSave As Worksheet
 
'---Check if not exactly one PT on Worksheet- exit
    If ws.PivotTables.Count <> 1 Then GoTo StopNotes
    Set PT = ws.PivotTables(1)
 
'---Check if not Compact Report layout- exit
    For Each ptField In PT.RowFields
        If Not ptField.LayoutCompactRow Then GoTo StopNotes
    Next ptField
 
'---Check if Named Range "PT_Notes" doesn't exist- define it
    If Not NameExists(sRngName, ws.Name) Then
        With PT.TableRange1
            Set rNotes = Intersect(PT.DataBodyRange.EntireRow, _
                    .Resize(, 1).Offset(0, .Columns.Count))
        End With
        Set rNotes = rNotes.Resize(rNotes.Rows.Count _
            + PT.ColumnGrand)
        ws.Names.Add Name:=sRngName, RefersTo:=rNotes
        Call Format_NoteRange(rNotes)
    End If
 
'---Check if "|Notes" Worksheet doesn't exist- add it
    If Not SheetExists(ws.Name & "|Notes") Then
        Set wsSave = ActiveSheet
        Sheets.Add
        ActiveSheet.Name = ws.Name & "|Notes"
        wsSave.Activate
    End If
 
'---Check if Notes DataTable doesn't exist- add it
    With Sheets(ws.Name & "|Notes")
        On Error Resume Next
        Set tblNotes = .ListObjects(1)
        If tblNotes Is Nothing Then
            .Cells(1) = "KeyPhrase"
            .Cells(1, 2) = "Note"
            Set tblNotes = .ListObjects.Add(xlSrcRange, _
                .Range("A1:B2"), , xlYes)
        End If
    End With
 
'---Check if any PT fields are not Table Headers - add
    With tblNotes
        For Each ptField In PT.RowFields
            If IsError(Application.Match(ptField.Name, .HeaderRowRange, 0)) Then
                .ListColumns.Add Position:=2
                .HeaderRowRange(1, 2) = ptField.Name
            End If
        Next ptField
    End With
    Check_Setup = True
    Exit Function
 
StopNotes:
    If NameExists(sRngName, ws.Name) Then
        Application.EnableEvents = False
        Call Clear_Notes_Range(ws)
        ws.Names(sRngName).Delete
        Application.EnableEvents = True
        Check_Setup = False
        Exit Function
    End If
End Function

 

Thanks!! 

5 Replies

  • The macro should be in a standard module created by selecting Insert > Module in the Visual Basic Editor.

    Code in the worksheet modules and in ThisWorkbook (both under Microsoft Excel Objects) won't be listed in the Macros dialog.

    • burnskrl's avatar
      burnskrl
      Copper Contributor

      Great! Thanks for that help. I created a new module and pasted the existing Macro code there. When I select to 'Run' the Macro, it is prompting me to name it, but wouldn't that cause it to be listed in the dialog?

       

       

      • Oh wait - I should have seen that!

        A macro is a procedure (Sub) without arguments. Your code is a function, not a procedure! Moreover, it has an argument ws. So you cannot run it as a macro.

        I apologize for missing that.

Resources