On the same subject, the following seems to be okay, but I just wanted to verify:
I defined functions which are called from my worksheet cells (whose formulas are hidden). I would like to add "Option Private Module" to the VB code so that my clients can not see the functions on their own. That shouldn't interfere with the functionality of the cells which already have the code, right?
I just wrote a couple of quick/easy UDFs and a Sub and tested. The UDF works fine with Option Private Module.
It sounds to me like you already have the sheet protected and the UDFs in places that you want.
If that is the case, while I agree with jtakw that Function procedures do not show up in the Macro Run Dialog anyways, having the Option Private Module in place (at least for me in Excel 2010) prevents the function from appearing in the little drop-down list that appears after you type in the equals sign. I mention in case this is advantage in keeping the UDF a tiny bit more "hidden" and as Mike mentioned, it's an awfully easy way of dropping Sub procedures out of the Macro Dialog.
As I did not see it mentioned:
If the user knows the name of a Function and any required args, as mentioned, the UDF can still be entered onto a sheet. At least for me (Excel 2010 for WIN), this includes Functions marked Private.
Further, in the Macro Dialog, you can enter the name of either a Sub or Function procedure (marked Private and/or in a Private Module) and as long as there are no required parameters, it'll run.
Actually, once you correctly enter the name of a Private Sub or Private Function into the Macro Dialog, the 'Run' button becomes enabled (Regardless of whether any arguments are required). If the VBProject is not protected, so does the 'Delete' button. 'Run' runs the code, or if there are missing args, returns the error. 'Delete' works regardless of missing arguments.
Once I password protected with view locked the project (and closing and reopening the wb of course), the only difference I noted was in that using the Macro Dialog, the 'Delete' button stays disabled.
Here's the cheesy code I used, in a Standard Module:
Rich (BB code):
Option Explicit
Option Private Module
Private Sub TestMacroDialogWithSub()
MsgBox "Hello world! (from TestMacroDialogWithSub)", 0&, vbNullString
End Sub
Private Function TestMacroDialogWithFunction(Optional ByVal s As String)
Application.Volatile
MsgBox "Greetings from TestMacroDialogWithFunction!" & _
IIf(Not (s = vbNullString), Space(2) & s, ""), _
0&, vbNullString
End Function
Private Function TestMacroDialogWithFunctionAndRequiredArg(ByVal Cell As Range)
Application.Volatile
MsgBox Cell.Value & " is the current value of " & Cell.Address(0, 0, 1)
End Function
Private Function MyFunction(ByVal CellRange As Range) As Double
Dim Cell As Range
Dim dblVal As Double
Dim dblSubTot As Double
For Each Cell In CellRange.Cells
If IsNumeric(Cell.Value) Then
dblVal = Val(Cell.Value)
dblSubTot = dblSubTot + dblVal
End If
Next
MyFunction = dblSubTot
End Function
Merry Christmas to all,
Mark