What does "Shift:=" mean in this VB6 code? - excel

I've run across the following line in a VB6 application.
mobjParentWrkBk.ExcelWorkBook.Application.Selection.Insert Shift:=xlToRight
Unfortunately Google and other search engines have not been very useful as they seem to omit the := part.
What would be a C# equivalent?

This is Visual Basic syntax for optional named parameters. The Insert function has a parameter named Shift, which is being specified.
C#, as far as I know, doesn't have an equivalent for optional named parameters. Instead, you'd need to call the Insert method, specifying Type.Missing for all parameters other than Shift.
See also the following StackOverflow question: VB.NET := Operator
UPDATE (2008-10-29):
C# 4.0 is set to introduce optional and named parameters. See this blog entry on codebetter.com.

Just to clarify John Rudy's response.
The sytax is optional (small 'o'), meaning you don't have to use it. In my experience, most VB6 coders don't use the syntax and instead prefer regular 'unnamed' parameters.
If you do choose to use it, all subsequent paramters in the sub procedure call must be named.
The named paramter syntax can be used on all parameters, whether or not the corresponding argument was declared using the VBA keyword Optional (capital 'O'). Consider, for example, this (slightly daft) VBA function with two parameters, one required and one Optional:
Private Function TimesTen( _
ByVal Value As Long, _
Optional ByVal Factor As Long = 10 _
) As Long
TimesTen = Value * Factor
End Function
In VBA, I can call it using named parameters for the required parameter (the Optional paramter can simply be omitted in VBA, unlike in C#.NET for which Type.Missing must be used for all omitted Optional parameters):
MsgBox TimesTen(Value:=9)
If I wanted to call it with the parameters in the 'wrong' order (why??) I can achieve this using named parameters:
MsgBox TimesTen(Factor:=11, Value:=9)
Trying to use a regular 'unnamed' parameter call after a named one causes a compile error:
MsgBox TimesTen(Value:=9, 11)
So why do VBA coders use named parameters if VB6 coders rarely do, even though they use essentially the same language? I think it is because the VBA generated by the MS Office applications' macro recorder tends to (always?) generate named parameters and many VBA coders learn programming this way.

VB6 and VB.net has optional parameters in method.
c# has the option to do method overloading.
VB6/VB.net way of saying Shift:=xlToRight allows passing value of a specific parameter by name.
e.g.
public sub mymethod(optional a as integer = -1, optional b as integer=1)
...
end sub
I can call this method with mymethod(b:=10)
For c#, there could be 2 methods for this
void Shift()
{
defaultDirection = directionEnum.Left;
Shift(defaultDirection);
}
void Shift(directionEnum direction)
{
}
1 more thing.
Although you can call method just by passing parameters, adding parameter name when calling makes code a little more readable.
e.g. DoSomethingWithData(CustomerData:= customer, SortDirection:=Ascending)
Hope that helps.

It's really all about Excel and how it handles inserts. If you select a range of cells and right-click Insert you will be asked which direction to shift the cells. This is from the Excel Help:
=======
Insert Method on Range Object
Inserts a cell or a range of cells into the worksheet or macro sheet and shifts other cells away to make space.
expression.Insert(Shift, CopyOrigin)
expression Required. An expression that returns a Range object.
Shift Optional Variant. Specifies which way to shift the cells. Can be one of the following XlInsertShiftDirection constants: xlShiftToRight or xlShiftDown. If this argument is omitted, Microsoft Excel decides based on the shape of the range.
CopyOrigin Optional Variant. The copy origin.
===========
If you don't have the constants defined you can subsitute the following numbers
xlShiftDown: -4121
xlShiftToLeft: -4159
xlShiftToRight: -4161
xlShiftUp: -4162

Related

Saving Excel macro with Parameters in Subroutine [duplicate]

I am writing VBA macros in excel 2016. Macros I write that have arguments do not show up in the Macro Table, only the ones that have no arguments. Help.
Macros that take arguments are not visible in the macro box because there is no point in having them there. If they need arguments to run, they cannot be run from the macro box because there is no way to supply an argument to the macro in question.
Normally, a macro shows up in the macro list when you display the
Macros dialog box (press Alt+F8), unless one of three conditions is
met:
The macro is a function. Functions typically return information,
and they require information to be passed to them. Since running a
macro from the macro list doesn't allow either of these things to
happen, Excel figures there is no need to list it. User-defined
functions, which are quite useful in Excel, are not displayed in the
Macros dialog box because they are, after all, functions.
The macro is
a subroutine with parameters. Excel assumes that since parameters are
necessary, and you cannot provide parameters by choosing the
subroutine from the macro list, there is no need to list it.
The subroutine has been declared Private. This means that the subroutine
is only useful to code within the module in which it is declared.
Source.
Depending on your need, a possible workaround is to use a helper-sub like this:
Sub InvisibleMacro(strArg As String)
MsgBox("The passed argument was " & strArg)
' This macro won't be visible in the macro dialog because it can only be called with an argument
End Sub
Sub VisibleMacro()
Call InvisibleMacro("Abc")
' This macro will be visible in the macro dialog because it requires no arguments and is not private.
' It will call the "invisible" macro with a preset argument.
End Sub
You can use InputBox or the likes if you need the passed argument to be non-static. Of course, depending on what datatype you need to pass as an argument, this approach may be limited and/or require some extra hoops.
Obviously if the macro requires parameters they can't be passed by clicking an icon.
But I have a Sub that only has one Optional parameter and that doesn't show up in the list either when trying to attach it to an icon in the customized ribbon.
Comment out the full Sub declaration and substitute a line without parameters, attach the macro to an icon, then put back the real line. The icon will still work.
' Temporarily use the parameterless line to set things up, then put
' back the real line. I assume this would crash if the Sub has required
' parameters.
Sub MySub()
' Sub MySub(Optional ByVal MyParm As String)
If MyParm = "" Then MyParm = "No parameter"
MsgBox (MyParm)
End Sub
I know this is an older post but I had the same issue. My fix was that I had to open the macros in the VB editor and then they showed up in the macro list. from there I could add them to the ribbon and change the icons. Hope this helps.
The macro is not listed when it has parameters, but knowing the name you should be able to simply write the name and theirs parameters when Excel prompts in the Assign Macro window, using single and double quotes.
The following example will guide you how to do it:
'mymacro "param1"'
'mymacro TRUE, FALSE'
'mymacro "param1","param2"'
My problem was that I had defined Macro directly through Visual Basic Editor in Excel and had defined it under "Class Modules" folder instead of "Modules"
Once I moved it into Modules folder, it was visible.
Hope this helps someone.
You probably have made macro as "Function()". To make it visible in macros list, you have to declare it as "Sub()".

Subs not appearing on Assign Macro list [duplicate]

I am writing VBA macros in excel 2016. Macros I write that have arguments do not show up in the Macro Table, only the ones that have no arguments. Help.
Macros that take arguments are not visible in the macro box because there is no point in having them there. If they need arguments to run, they cannot be run from the macro box because there is no way to supply an argument to the macro in question.
Normally, a macro shows up in the macro list when you display the
Macros dialog box (press Alt+F8), unless one of three conditions is
met:
The macro is a function. Functions typically return information,
and they require information to be passed to them. Since running a
macro from the macro list doesn't allow either of these things to
happen, Excel figures there is no need to list it. User-defined
functions, which are quite useful in Excel, are not displayed in the
Macros dialog box because they are, after all, functions.
The macro is
a subroutine with parameters. Excel assumes that since parameters are
necessary, and you cannot provide parameters by choosing the
subroutine from the macro list, there is no need to list it.
The subroutine has been declared Private. This means that the subroutine
is only useful to code within the module in which it is declared.
Source.
Depending on your need, a possible workaround is to use a helper-sub like this:
Sub InvisibleMacro(strArg As String)
MsgBox("The passed argument was " & strArg)
' This macro won't be visible in the macro dialog because it can only be called with an argument
End Sub
Sub VisibleMacro()
Call InvisibleMacro("Abc")
' This macro will be visible in the macro dialog because it requires no arguments and is not private.
' It will call the "invisible" macro with a preset argument.
End Sub
You can use InputBox or the likes if you need the passed argument to be non-static. Of course, depending on what datatype you need to pass as an argument, this approach may be limited and/or require some extra hoops.
Obviously if the macro requires parameters they can't be passed by clicking an icon.
But I have a Sub that only has one Optional parameter and that doesn't show up in the list either when trying to attach it to an icon in the customized ribbon.
Comment out the full Sub declaration and substitute a line without parameters, attach the macro to an icon, then put back the real line. The icon will still work.
' Temporarily use the parameterless line to set things up, then put
' back the real line. I assume this would crash if the Sub has required
' parameters.
Sub MySub()
' Sub MySub(Optional ByVal MyParm As String)
If MyParm = "" Then MyParm = "No parameter"
MsgBox (MyParm)
End Sub
I know this is an older post but I had the same issue. My fix was that I had to open the macros in the VB editor and then they showed up in the macro list. from there I could add them to the ribbon and change the icons. Hope this helps.
The macro is not listed when it has parameters, but knowing the name you should be able to simply write the name and theirs parameters when Excel prompts in the Assign Macro window, using single and double quotes.
The following example will guide you how to do it:
'mymacro "param1"'
'mymacro TRUE, FALSE'
'mymacro "param1","param2"'
My problem was that I had defined Macro directly through Visual Basic Editor in Excel and had defined it under "Class Modules" folder instead of "Modules"
Once I moved it into Modules folder, it was visible.
Hope this helps someone.
You probably have made macro as "Function()". To make it visible in macros list, you have to declare it as "Sub()".

How to use excel built-in constant in VBS [duplicate]

This question already has answers here:
Getting an error `xlValues` is not defined when Cells format to the others
(3 answers)
Closed 6 years ago.
I want to use VBScript to process EXCEL instead of VBA. But I encountered code errors when calling method Range.Find, see below
Function find_range(wb, domain, var)
Dim sheet
Dim rg1, rg2, rg3
Set sheet = wb.Sheets(domain)
Set rg1 = sheet.Range("D:D").Find(var, , xlValues, xlWhole )
If Not rg1 is Nothing Then
'msgbox rg1.Cells(1,1).row
Set rg2 = sheet.Cells(rg1.Cells(1,1).row, 19)
msgbox(rg2.value)
End if
End Function
when executed find_range function, I got
variable is undefined "xlValues" "xlWhole"
error.
So I guess that I cannot just use excel built-in constants this way in VBScript.
So what is the correct way?
Unfortunately these Named Constants are part of the Excel Object Library which VBScript has no way of referencing so the best approach is to lookup the named constants in Object Browser inside Excel VBA or online via various references then create your own named constants and use them in your code.
In this example you are using two enumerations that can be identified by looking up the Range.Find() method.
xlValues is a named constant in the xlFindLookIn enumeration and has the value -4163.
xlWhole is a named constant in the xlLookAt enumeration and has a value of 1.
So once you know the value you can define them and your code should work without any more changes being required.
Const xlValues = -4163
Const xlWhole = 1
Ideally these values should be declared in the global scope of your script so they are accessible to any function or procedure.
You might ask why not specify the numeric value? Well while this is indeed a valid approach if you use the value in multiple places you then have to modify that value in multiple places if the value ever changes (however unlikely in this scenario). With a named constant you make one change and wherever in your code that value is referenced is also changed.
It's also worth noting that VBScript is only interested in the numeric value so technically you can name the constants anything you wish. However, it is good practice to follow the naming convention, especially if you re-used the function code in Excel VBA for example.

Why do I get a 1004 Error when I try to write into a range passed as parameter in a function?

I am writing an Excel function and I want that it optionally can write a second result into a
Public Function foo(A As String, B As String, C As String, Optional optionalRes As Range = Nothing)
...
If not optionalRes is Nothing then
optionalRes.Value="Result!"
End If
End Function
Unfortunately, this does not work I get this error: Error 1004 (Application-defined or object-defined error) in procedure foo of Module fooBar.
Is what I am trying to do at least possible?
Thanks in advance for looking at this issue with me!
You should use a Sub rather than a UDF.
UDFs are used to return values rather than change cells via a side-effect.
There's a couple points to consider here...
Note typo in your function definition, which could be avoided by using Option Explicit. optionaRes != optionalRes. But I think that should raise a 424, not a 1004.
Also, worth noting: It's generally not possible to use a UDF called from the worksheet to manipulate the worksheet objects in any manner whatsoever.
This may not apply to you, if you are calling this function from elsewhere in VBA code (and not from a user-defined worksheet function), but I would still recommend against using functions to manipulate objects. That should be done by subroutines, and use functions to return values or evaluate expressions, etc.

Creating a custom hyperlink function in excel

I have searched far and wide, but can't find an answer to this simple question. I want to make a custom function in excel which will create a hyperlink.
Excel has a built in hyperlink function that works like this:
=Hyperlink(link_location, display_text)
I want to create a function called CustomHyperlink which takes one parameter, and returns a hyperlink to a google query with that parameter. Just for the sake of the question, lets assume that the passed parameter is a alphanumeric string, with no spaces.
Essentially, calling
=CustomHyperlink("excel")
should be the same as calling
=Hyperlink("http://www.google.com/search?q=excel", "excel")
This seems like such a simple task, but I absolutely cannot find a way to make this function.
Can anyone offer some quick help?
I can offer a partial solution, one that will update an existing hyperlink. This only makes sence if you are using it like, say
CustomHyperlink(A1)
were A1 contains the required serch term
To use,
enter your UDF formula in a cell, eg =CustomHyperlink(A1)
create a hyperlink on the cell (right click, Hyperlink...) . This can be any hyperlink, valid or invalid
put the required search term in the referenced cell, eg in A1 put excel
When the UDF runs it will update the hyperlink to Google the entered search term
Function CustomHyperlink(Term As String) As String
Dim rng As Range
Set rng = Application.Caller
CustomHyperlink = Term
If rng.Hyperlinks.Count > 0 Then
rng.Hyperlinks(1).Address = "http://www.google.com/search?q=" & Term
End If
End Function
In VBA editor you can use
ThisWorkbook.FollowHyperlink Address:=(strWebsite), NewWindow:=True
Which will take you to that specific website, and just build a function around that to navigate you to the site you need.
Nice idea although this isn't possible.
You seem to want to have the formula of the cell as one thing (your custom function call) and yet have the value as another (the hyperlink / URL) which simply isn't possible.
The correct way through VBA to add a hyperlink is to use the Hyperlinks property but it is not possible to call this property, through a Worksheet UDF (because of the reason above).
What is wrong with just using the the built-in =Hyperlink() worksheet function? You could effectively parameterise your URL as follows (where cell A1 = Excel):
=HYPERLINK("http://www.google.com/search?q="&A1)
You can't do this directly for the reasons creamyegg suggests, but there is a way to achieve the functionality albeit with a bit of a performance consideration.
You could use the Worksheet_Change event to track for the presence of your UDF then process the hyperlink addition there.
You would need to set up an empty function to allow this to happen, otherwise Excel will throw an error whenever you entered =CustomHyperlink... in a cell.
The below should work, not really had time to test.
Private Sub worksheet_change(ByVal target As Range)
Dim SearchValue As String
If LCase(Left(target.Formula, 16)) = "=customhyperlink" Then
SearchValue = Mid(target.Formula, 19, Len(target.Formula) - 20)
target.Value = SearchValue
target.Hyperlinks.Add target, "http://www.google.com/search?q=" & SearchValue, , "Search Google for " & SearchValue, SearchValue
End If
End Sub
The performance consideration is of course the volatile Worksheet_Change event as this can really kill large, complex workbooks.

Resources