How do I extract a series of numbers along with a single letter followed by another series of numbers? - excel

The problem that I'm facing is that I have an entire column that has text separated by _ that contains pixel size that I want to be able to extract but currently can't. For example:
A
Example_Number_320x50_fifty_five
Example_Number_One_300x250_hundred
Example_Number_two_fifty_728x49
I have tried using Substitute function to grab the numbers which works but only grabs the numbers when I need something like: 320x50 instead I'm getting 0, as I'm not sure how to exactly extract something like this. If it was consistent I could easily do LEFT or RIGHT formula's to grab it but as you can see the data varies.
The result that I'm looking for is something along the lines of:
A | B
Example_Number_320x50_fifty_five | 320x50
Example_Number_One_300x250_hundred | 300x200
Example_Number_two_fifty_728x49 | 728x49
Any help would be much appreciated! If any further clarification is needed please let me know and I'll try to explain as best as I can!
-Maykid

I would probably use a Regular Expressions UDF to accomplish this.
First, open up the VBE by pressing Alt + F11.
Right-Click on VBAProject > Insert > Module
Then you can paste the following code in your module:
Option Explicit
Public Function getPixelDim(RawTextValue As String) As String
With CreateObject("VBScript.RegExp")
.Pattern = "\d+x\d+"
If .Test(RawTextValue) Then
getPixelDim = .Execute(RawTextValue)(0)
End If
End With
End Function
Back to your worksheet, you would use the following formula:
=getPixelDim(A1)
Looking at the pattern \d+x\d+, an escaped d (\d) refers to any digit, a + means one or more of \d, and the x is just a literal letter x. This is the pattern you want to capture as your function's return value.

Gosh, K Davis was just so fast! Here's an alternate method with similar concept.
Create a module and create a user defined function like so.
Public Function GetPixels(mycell As Range) As String
Dim Splitter As Variant
Dim ReturnValue As String
Splitter = Split(mycell.Text, "_")
For i = 0 To UBound(Splitter)
If IsNumeric(Mid(Splitter(i), 1, 1)) Then
ReturnValue = Splitter(i)
Exit For
End If
Next
GetPixels = ReturnValue
End Function
In your excel sheet, type in B1 the formula =GetPixels(A1) and you will get 320x50.
How do you create a user defined function?
Developer tab
Use this URL to add Developer tab if you don't have it: https://www.addintools.com/documents/excel/how-to-add-developer-tab.html
Click on the highlighted areas to get to Visual Basic for Applications (VBA) window.
Create module
Click Insert > Module and then type in the code.
Use the user defined function
Note how the user defined function is called.

Related

Filter phone numbers from open text field - Power BI, excel, VBA

I have a text field in a table where I need to substitute phone numbers where applicable.
For example the text field could have:
Call me on 08588812885 immediately
Call me on 07525812845
I need assistance please contact me
Good service
Sometimes a phone number will be in the text but not always and the phone number entered will always be different.
Is there a measure to use to replace the phone numbers with no text.
Ideally the solution would be Power BI, but can also be done in the raw data using excel or VBA
Regular expression in VBA (excel) or Python (Power BI) is a straightforward solution.
I have never used PowerBI with Python before but manage to make following python script.
In PowerBI transformation steps I created a new column that would copy [message] columns and named it [noPhoneNumber], then next step ran this python script
import re
def removePhone(x):
return re.sub('\d{10,11}', "**number removed**", x)
length = len(dataset["noPhoneNumber"])
for iRow in range(length):
dataset["noPhoneNumber"][iRow] = removePhone(dataset["noPhoneNumber"][iRow])
so column "noPhoneNumber"
Call me on 08588812885 immediately
Call me on 07525812845
I need assistance please contact me
Good service
becomes
Call me on **number removed** immediately
Call me on **number removed**
I need assistance please contact me
Good service
In VBA Preferable create UDF (user defined function) and don't create a subroutine, that would be too error prone for this kind of problem.
[Added]
If you need to make a Excel based solution, you can create a UDF function like so:
(remember early binding to import of VBScript_RegExp_55.RegExp in excel)
Function removePhoneNumber(text As String, Optional replacement As String = "**number removed**") As String
Dim regex As New RegExp
regex.Pattern = "\d{10,11}"
removePhoneNumber = regex.Replace(text, replacement)
End Function
...and then use excel function like so:
=removePhoneNumber(A2),
=removePhoneNumber(A3)
and so on...
A simple VBA function alternative
Function removePhone(s As String) As String
Const DELIM As String = " "
Dim i As Long, tokens As Variant
tokens = Split(s, DELIM)
For i = LBound(tokens) To UBound(tokens)
If IsNumeric(tokens(i)) Then
tokens(i) = "*Removed*" ' << change to your needs
Exit For ' assuming a single phone number per string
End If
Next
removePhone = Join(tokens, DELIM)
End Function
You can do this in Power Query. Create a custom column with this below code. I have considered the column name is Comments but please adjust this with your column name.
if Text.Length(Text.Select([comments], {"0".."9"})) = 11
then
Text.Replace(
[comments],
Text.Select([comments], {"0".."9"}),
""
)
else [comments]
Here is the output below. You can also replace phone numbers with other text like #### to make is anonymous.
NOTE
This will only work if there are only 1 number in the string with length 11 (You can adjust the length in code as per requirement).
This will Not work if there are more than one Numbers in the string.
If there are 1 number in the string but length not equal 11, this will keep the whole string as original.

Excel find and replace function correct formula

I wish to use the find and replace function in excel to remove example sentences from cells similar to this:
text <br>〔「text」text,「text」text〕<br>(1)text「sentence―sentence/sentence」<br>(2)text「sentence―sentence」
Sentences are in between 「」brackets and will include a ― and / character somewhere inside the brackets.
I have tried 「*―*/*」 however this will delete everything from the right of the〔
Is there any way to target and delete these specific sentence brackets, with the find and replace tool?
Desired outcome:
text <br>〔「text」text,「text」text〕<br>(1)text<br>(2)text「sentence―sentence」
Quite a long formula but in Excel O365 you could use:
=SUBSTITUTE(CONCAT(FILTERXML("<t><s>"&SUBSTITUTE(CONCAT(IF(MID(A1,SEQUENCE(LEN(A1)),1)="「","</s><s>「",IF(MID(A1,SEQUENCE(LEN(A1)),1)="」","」</s><s>",MID(A1,SEQUENCE(LEN(A1)),1)))),"<br>","|$|")&"</s></t>","//s[not(contains(., '「') and contains(., '―') and contains(., '/') and contains(., '」'))][node()]")),"|$|","<br>")
As long as you have access to CONCAT you could also do this in Excel 2019 but you'll have to swap SEQUENCE(LEN(A1)) for ROW(A$1:INDEX(A:A,LEN(A1)))
This formula won't work in many cases, but if the string has matching rules as in your example, then try this:
=SUBSTITUTE(C5,"「" & INDEX(TRIM(MID(SUBSTITUTE(","&SUBSTITUTE(C5,"」","「"),"「",REPT(" ",99)),(ROW(A1:INDEX(A1:A100,LEN(C5)-LEN(SUBSTITUTE(C5,"」",""))))*2-1)*99,99)),MATCH("*―*/*",TRIM(MID(SUBSTITUTE(","&SUBSTITUTE(C5,"」","「"),"「",REPT(" ",99)),(ROW(A1:INDEX(A1:A100,LEN(C5)-LEN(SUBSTITUTE(C5,"」",""))))*2-1)*99,99)),0)) & "」","")
explain how it works:
split the string between the characters "「 "and "」" into an array
use match("*―*/*",,0) to find the string position (note that it will only return one value if it exists, if you have multiple strings, you can replace match("*―*/*",) with search ("*―*/*",..) and use it as an extra column to get matches string)
Use the index(array,match("*―*/*",..)) to get the string needs replacing (result)
Replace the original string with the results found =substitute(txt,result,"")
Or,
In B1 enter formula :
=SUBSTITUTE(A1,"「"&TRIM(RIGHT(SUBSTITUTE(LEFT(A1,FIND("」",A1,FIND("/",A1))),"「",REPT(" ",99)),99)),"")
You did not tag [VBA], but if you are not averse, you could write a User Defined Function that would do what you want using Regular Expressions.
To enter this User Defined Function (UDF), alt-F11 opens the Visual Basic Editor.
Ensure your project is highlighted in the Project Explorer window.
Then, from the top menu, select Insert/Module and
paste the code below into the window that opens.
To use this User Defined Function (UDF), enter a formula like =replStr(A1) in some cell.
Option Explicit
Function replStr(str As String) As String
Dim RE As Object
Const sPat As String = "\u300C(?:(?=[^\u300D]*\u002F)(?=[^\u300D]*\u2015)[^\u300D]*)\u300D"
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = sPat
replStr = .Replace(str, "")
End With
End Function

Remove text appearing between two characters - multiple instances - Excel

In Microsoft Excel file, I have a text in rows that appears like this:
1. Rc8 {[%emt 0:00:05]} Rxc8 {[%emt 0:00:01]} 2. Rxc8 {[%emt 0:00:01]} Qxc8 {} 3. Qe7# 1-0
I need to remove any text appearing within the flower brackets { and }, including the brackets themselves.
In the above example, there are three instances of such flower brackets. But some rows might have more than that.
I tried =MID(LEFT(A2,FIND("}",A2)-1),FIND("{",A2)+1,LEN(A2))
This outputs to: {[%emt 0:00:05]}. As you see this is the very first instance of text between those flower brackets.
And if we use this to within SUBSTITUTE like this: =SUBSTITUTE(A2,MID(LEFT(A2,FIND("}",A2)),FIND("{",A2),LEN(A2)),"")
I get an output like this:
1. Rc8 Rxc8 {[%emt 0:00:01]} 2. Rxc8 {[%emt 0:00:01]} Qxc8 {} 3. Qe7# 1-0
If you have noticed, only one instance is removed. How do I make it work for all instances? thanks.
Highlight everything
Go to replace
enter {*} in text to replace
leave replace with blank
This should replace all flower brackets and anything in between them
It is not that easy without VBA, but there is still a way.
Either (as suggested by yu_ominae) just use a formula like this and auto-fill it:
=IFERROR(SUBSTITUTE(A2,MID(LEFT(A2,FIND("}",A2)),FIND("{",A2),LEN(A2)),""),A2)
Another way would be iterative calculations (go to options -> formulas -> check the "enable iterative calculations" button)
To do it now in one cell, you need 1 helper-cell (for my example we will use C1) and the use a formula like this in B2 and auto-fill down:
=IF($C$1,A2,IFERROR(SUBSTITUTE(B2,MID(LEFT(B2,FIND("}",B2)),FIND("{",B2),LEN(B2)),""),B2))
Put "1" in C1 and all formulas in B:B will show the values of A:A. Now go to C1 and hit the del-key several times (you will see the "{}"-parts disappearing) till all looks like you want it.
EDIT: To do it via VBA but without regex you can simply put this into a module:
Public Function DELBRC(ByVal str As String) As String
While InStr(str, "{") > 0 And InStr(str, "}") > InStr(str, "{")
str = Left(str, InStr(str, "{") - 1) & Mid(str, InStr(str, "}") + 1)
Wend
DELBRC = Trim(str)
End Function
and then in the worksheet directly use:
=DELBRC(A2)
If you still have any questions, just ask ;)
Try a user defined function. In VBA create a reference to "Microsoft VBScript Regular Expressions 5.5. Then add this code in a module.
Function RemoveTags(ByVal Value As String) As String
Dim rx As New RegExp
rx.Global = True
rx.Pattern = " ?{.*?}"
RemoveTags = Trim(rx.Replace(Value, ""))
End Function
On the worksheet in the cell enter: =RemoveTags(A1) or whatever the address is where you want to remove text.
If you want to test it in VBA:
Sub test()
Dim a As String
a = "Rc8 {[%emt 0:00:05]} Rxc8 {[%emt 0:00:01]}"
Debug.Print RemoveTags(a)
End Sub
Outputs "Rc8 Rxc8"

How to show the parameters of an UDF when typing the function in Excel-Vba? [duplicate]

In Excel 2007, how do I add a description and parameter hints to a user-defined function? When I start typing a function invocation for a built-in function, Excel shows a description and parameter list--a tooltip. I'd like to do the same for the functions I define.
Not just for the formula insert wizard, but in the formula box, so if I key "=myFun(", at the "(" the tooltip pops up just like it does for "=average("
There's no help in VBA Help, none on MSDN and none on any of the Excel and VBA dedicated forums I can find, so this is clearly a long shot.
Not a tooltip solution but an adequate workaround:
Start typing the UDF =MyUDF( then press CTRL + Shift + A and your function parameters will be displayed. So long as those parameters have meaningful names you at-least have a viable prompt
For example, this:
=MyUDF( + CTRL + Shift + A
Turns into this:
=MyUDF(sPath, sFileName)
Professional Excel Development by
Stephen Bullen describes how to
register UDFs, which allows a
description to appear in the Function
Arguments dialog:
Function IFERROR(ByRef ToEvaluate As Variant, ByRef Default As Variant) As Variant
If IsError(ToEvaluate) Then
IFERROR = Default
Else
IFERROR = ToEvaluate
End If
End Function
Sub RegisterUDF()
Dim s As String
s = "Provides a shortcut replacement for the common worksheet construct" & vbLf _
& "IF(ISERROR(<expression>), <default>, <expression>)"
Application.MacroOptions macro:="IFERROR", Description:=s, Category:=9
End Sub
Sub UnregisterUDF()
Application.MacroOptions Macro:="IFERROR", Description:=Empty, Category:=Empty
End Sub
From: http://www.ozgrid.com/forum/showthread.php?t=78123&page=1
To show the Function Arguments dialog, type the function name and press CtrlA. Alternatively, click the "fx" symbol in the formula bar:
I know you've accepted an answer for this, but there's now a solution that lets you get an intellisense style completion box pop up like for the other excel functions, via an Excel-DNA add in, or by registering an intellisense server inside your own add in. See here.
Now, i prefer the C# way of doing it - it's much simpler, as inside Excel-DNA, any class that implements IExcelAddin is picked up by the addin framework and has AutoOpen() and AutoClose() run when you open/close the add in. So you just need this:
namespace MyNameSpace {
public class Intellisense : IExcelAddIn {
public void AutoClose() {
}
public void AutoOpen() {
IntelliSenseServer.Register();
}
}
}
and then (and this is just taken from the github page), you just need to use the ExcelDNA annotations on your functions:
[ExcelFunction(Description = "A useful test function that adds two numbers, and returns the sum.")]
public static double AddThem(
[ExcelArgument(Name = "Augend", Description = "is the first number, to which will be added")]
double v1,
[ExcelArgument(Name = "Addend", Description = "is the second number that will be added")]
double v2)
{
return v1 + v2;
}
which are annotated using the ExcelDNA annotations, the intellisense server will pick up the argument names and descriptions.
There are examples for using it with just VBA too, but i'm not too into my VBA, so i don't use those parts.
Also you can use, this Macro to assign Descriptions to arguments and the UDF:
Private Sub RegisterMyFunction()
Application.MacroOptions _
Macro:="SampleFunction", _ '' Your UDF name
Description:="calculates a result based on provided inputs", _
Category:="My UDF Category", _ '' Or use numbers, a list in the link below
ArgumentDescriptions:=Array( _ '' One by each argument
"is the first argument. tell the user what it does", _
"is the second argument. tell the user what it does")
End Sub
Credits to Kendall and the original post here.
For the UDF Categories
I just create a "help" version of the function. Shows up right below the function in autocomplete - the user can select it instead in an adjacent cell for instructions.
Public Function Foo(param1 as range, param2 as string) As String
Foo = "Hello world"
End Function
Public Function Foo_Help() as String
Foo_Help = "The Foo function was designed to return the Foo value for a specified range a cells given a specified constant." & CHR(10) & "Parameters:" & CHR(10)
& " param1 as Range : Specifies the range of cells the Foo function should operate on." & CHR(10)
&" param2 as String : Specifies the constant the function should use to calculate Foo"
&" contact the Foo master at master#foo.com for more information."
END FUNCTION
The carriage returns improve readability with wordwrap on. 2 birds with one stone, now the function has some documentation.
#will's method is the best. Just add few lines about the details for the people didn't use ExcelDNA before like me.
Download Excel-DNA IntelliSense from https://github.com/Excel-DNA/IntelliSense/releases
There are two version, one is for 64, check your Excel version. For my case, I'm using 64 version.
Open Excel/Developer/Add-Ins/Browse and select ExcelDna.IntelliSense64.xll.
Insert a new sheet, change name to "IntelliSense", add function description, as https://github.com/Excel-DNA/IntelliSense/wiki/Getting-Started
Then enjoy! :)
Unfortunately there is no way to add Tooltips for UDF Arguments.
To extend Remou's reply you can find a fuller but more complex approach to descriptions for the Function Wizard at
http://www.jkp-ads.com/Articles/RegisterUDF00.asp
I tried #ScottK's approach, first as a side feature of my functional UDF, then as a standalone _Help suffix version when I ran into trouble (see below). In hindsight, the latter approach is better anyway--more obvious to a user attentive enough to see a tool tip, and it doesn't clutter up the functional code.
I figured if an inattentive user just typed the function name and closed the parentheses while he thought it over, help would appear and he would be on his way. But dumping a bunch of text into a single cell that I cannot format didn't seem like a good idea. Instead, When the function is entered in a cell with no arguments i.e.
= interpolateLinear()
or
= interpolateLinear_Help()
a msgBox opens with the help text. A msgBox is limited to ~1000 characters, maybe it's 1024. But that's enough (barely 8^/) for my overly tricked out interpolation function. If it's not, you can always open a user form and go to town.
The first time the message box opened, it looked like success. But there are a couple of problems. First of course, the user has to know to enter the function with no arguments (+1 for the _Help suffix UDF).
The big problem is, the msgBox reopens several times in succession, spontaneously while working in unrelated parts of the workbook. Needless to say, it's very annoying. Sometimes it goes on until I get a circular reference warning. Go figure. If a UDF could change the cell formula, I would have done that to shut it up.
I don't know why Excel feels the need recalculate the formula over and over; neither the _Help standalone, nor the full up version (in help mode) has precedents or dependents. There's not an application.volatile statement anywhere. Of course the function returns a value to the calling cell. Maybe that triggers the recalc? But that's what UDFs do. I don't think you can not return a value.
Since you can't modify a worksheet formula from a UDF, I tried to return a specific string --a value --to the calling cell (the only one you can change the value of from a UDF), figuring I would inspect the cell value using application.caller on the next cycle, spot my string, and know not to re-display the help message. Seemed like a good idea at the time--didn't work. Maybe I did something stupid in my sleep-deprived state. I still like the idea. I'll update this when (if) I fix the problem. My quick fix was to add a line on the help box: "Seek help only in an emergency. Delete the offending formula to end the misery.
In the meantime, I tried the Application.MacroOptions approach. Pretty easy, and it looks professional. Just one problem to work out. I'll post a separate answer on that approach later.
A lot of dancing around the answer. You can add the UDF context help, but you have to export the Module and edit the contents in a text editor, then re-import it to VBA. Here's the example from Chip Pearson: Adding Code Attributes

How to put a tooltip on a user-defined function

In Excel 2007, how do I add a description and parameter hints to a user-defined function? When I start typing a function invocation for a built-in function, Excel shows a description and parameter list--a tooltip. I'd like to do the same for the functions I define.
Not just for the formula insert wizard, but in the formula box, so if I key "=myFun(", at the "(" the tooltip pops up just like it does for "=average("
There's no help in VBA Help, none on MSDN and none on any of the Excel and VBA dedicated forums I can find, so this is clearly a long shot.
Not a tooltip solution but an adequate workaround:
Start typing the UDF =MyUDF( then press CTRL + Shift + A and your function parameters will be displayed. So long as those parameters have meaningful names you at-least have a viable prompt
For example, this:
=MyUDF( + CTRL + Shift + A
Turns into this:
=MyUDF(sPath, sFileName)
Professional Excel Development by
Stephen Bullen describes how to
register UDFs, which allows a
description to appear in the Function
Arguments dialog:
Function IFERROR(ByRef ToEvaluate As Variant, ByRef Default As Variant) As Variant
If IsError(ToEvaluate) Then
IFERROR = Default
Else
IFERROR = ToEvaluate
End If
End Function
Sub RegisterUDF()
Dim s As String
s = "Provides a shortcut replacement for the common worksheet construct" & vbLf _
& "IF(ISERROR(<expression>), <default>, <expression>)"
Application.MacroOptions macro:="IFERROR", Description:=s, Category:=9
End Sub
Sub UnregisterUDF()
Application.MacroOptions Macro:="IFERROR", Description:=Empty, Category:=Empty
End Sub
From: http://www.ozgrid.com/forum/showthread.php?t=78123&page=1
To show the Function Arguments dialog, type the function name and press CtrlA. Alternatively, click the "fx" symbol in the formula bar:
I know you've accepted an answer for this, but there's now a solution that lets you get an intellisense style completion box pop up like for the other excel functions, via an Excel-DNA add in, or by registering an intellisense server inside your own add in. See here.
Now, i prefer the C# way of doing it - it's much simpler, as inside Excel-DNA, any class that implements IExcelAddin is picked up by the addin framework and has AutoOpen() and AutoClose() run when you open/close the add in. So you just need this:
namespace MyNameSpace {
public class Intellisense : IExcelAddIn {
public void AutoClose() {
}
public void AutoOpen() {
IntelliSenseServer.Register();
}
}
}
and then (and this is just taken from the github page), you just need to use the ExcelDNA annotations on your functions:
[ExcelFunction(Description = "A useful test function that adds two numbers, and returns the sum.")]
public static double AddThem(
[ExcelArgument(Name = "Augend", Description = "is the first number, to which will be added")]
double v1,
[ExcelArgument(Name = "Addend", Description = "is the second number that will be added")]
double v2)
{
return v1 + v2;
}
which are annotated using the ExcelDNA annotations, the intellisense server will pick up the argument names and descriptions.
There are examples for using it with just VBA too, but i'm not too into my VBA, so i don't use those parts.
Also you can use, this Macro to assign Descriptions to arguments and the UDF:
Private Sub RegisterMyFunction()
Application.MacroOptions _
Macro:="SampleFunction", _ '' Your UDF name
Description:="calculates a result based on provided inputs", _
Category:="My UDF Category", _ '' Or use numbers, a list in the link below
ArgumentDescriptions:=Array( _ '' One by each argument
"is the first argument. tell the user what it does", _
"is the second argument. tell the user what it does")
End Sub
Credits to Kendall and the original post here.
For the UDF Categories
I just create a "help" version of the function. Shows up right below the function in autocomplete - the user can select it instead in an adjacent cell for instructions.
Public Function Foo(param1 as range, param2 as string) As String
Foo = "Hello world"
End Function
Public Function Foo_Help() as String
Foo_Help = "The Foo function was designed to return the Foo value for a specified range a cells given a specified constant." & CHR(10) & "Parameters:" & CHR(10)
& " param1 as Range : Specifies the range of cells the Foo function should operate on." & CHR(10)
&" param2 as String : Specifies the constant the function should use to calculate Foo"
&" contact the Foo master at master#foo.com for more information."
END FUNCTION
The carriage returns improve readability with wordwrap on. 2 birds with one stone, now the function has some documentation.
#will's method is the best. Just add few lines about the details for the people didn't use ExcelDNA before like me.
Download Excel-DNA IntelliSense from https://github.com/Excel-DNA/IntelliSense/releases
There are two version, one is for 64, check your Excel version. For my case, I'm using 64 version.
Open Excel/Developer/Add-Ins/Browse and select ExcelDna.IntelliSense64.xll.
Insert a new sheet, change name to "IntelliSense", add function description, as https://github.com/Excel-DNA/IntelliSense/wiki/Getting-Started
Then enjoy! :)
Unfortunately there is no way to add Tooltips for UDF Arguments.
To extend Remou's reply you can find a fuller but more complex approach to descriptions for the Function Wizard at
http://www.jkp-ads.com/Articles/RegisterUDF00.asp
I tried #ScottK's approach, first as a side feature of my functional UDF, then as a standalone _Help suffix version when I ran into trouble (see below). In hindsight, the latter approach is better anyway--more obvious to a user attentive enough to see a tool tip, and it doesn't clutter up the functional code.
I figured if an inattentive user just typed the function name and closed the parentheses while he thought it over, help would appear and he would be on his way. But dumping a bunch of text into a single cell that I cannot format didn't seem like a good idea. Instead, When the function is entered in a cell with no arguments i.e.
= interpolateLinear()
or
= interpolateLinear_Help()
a msgBox opens with the help text. A msgBox is limited to ~1000 characters, maybe it's 1024. But that's enough (barely 8^/) for my overly tricked out interpolation function. If it's not, you can always open a user form and go to town.
The first time the message box opened, it looked like success. But there are a couple of problems. First of course, the user has to know to enter the function with no arguments (+1 for the _Help suffix UDF).
The big problem is, the msgBox reopens several times in succession, spontaneously while working in unrelated parts of the workbook. Needless to say, it's very annoying. Sometimes it goes on until I get a circular reference warning. Go figure. If a UDF could change the cell formula, I would have done that to shut it up.
I don't know why Excel feels the need recalculate the formula over and over; neither the _Help standalone, nor the full up version (in help mode) has precedents or dependents. There's not an application.volatile statement anywhere. Of course the function returns a value to the calling cell. Maybe that triggers the recalc? But that's what UDFs do. I don't think you can not return a value.
Since you can't modify a worksheet formula from a UDF, I tried to return a specific string --a value --to the calling cell (the only one you can change the value of from a UDF), figuring I would inspect the cell value using application.caller on the next cycle, spot my string, and know not to re-display the help message. Seemed like a good idea at the time--didn't work. Maybe I did something stupid in my sleep-deprived state. I still like the idea. I'll update this when (if) I fix the problem. My quick fix was to add a line on the help box: "Seek help only in an emergency. Delete the offending formula to end the misery.
In the meantime, I tried the Application.MacroOptions approach. Pretty easy, and it looks professional. Just one problem to work out. I'll post a separate answer on that approach later.
A lot of dancing around the answer. You can add the UDF context help, but you have to export the Module and edit the contents in a text editor, then re-import it to VBA. Here's the example from Chip Pearson: Adding Code Attributes

Resources