SlicersCaches.add and Slicers.Add gives error when I name the parameters but works fine without.
Error:
Set SC1 = ActiveWorkbook.SlicerCaches.Add(Source:=PivTable Sourcefield:="Dept")
Set SL1 = SC1.Slicers.Add(Slicerdestination:=PivSheet)
No Error:
Set SC1 = ActiveWorkbook.SlicerCaches.Add(PivTable, "Dept")
Set SL1 = SC1.Slicers.Add(PivSheet)
Is this a bug in the program?
There are no bugs in the program. When you call a Sub or Function procedure, you can supply arguments positionally, in the order they appear in the procedure's definition, or you can supply the arguments by name without regard to position.
Named arguments are especially useful when you are calling a procedure that has optional arguments. If you use named arguments, you don't have to include commas to denote missing positional arguments. Using named arguments makes it easier to keep track of which arguments you passed and which you omitted.
When you call a procedure with an optional argument, you can choose whether or not to specify the optional argument. If you don't specify the optional argument, the default value, if any, is used. If no default value is specified, the argument is it would be for any variable of the specified type.
Below are the complete definitions of the slicer functions with arguments (optional in square brackets):
Slicer.Add
Add(SlicerDestination, [Level], [Name], [Caption], [Top], [Left], [Width], [Height]) As Slicer
SlicerCache.Add
Add(Source, SourceField, [Name]) As SlicerCache
Related
Sub Main()
Console.WriteLine("check")
Console.Read()
End Sub
Why does Sub Main () need them? How do they apply to this procedure?
.WriteLine("") here i am adding a value.
Console.Read() is this holding the value "check" to show on console? Why why are they here.
I know all you experts think this is a dumb question, however i can not wrap my head around it help! To me these are boxes that hold or pass a procedure value.
Is sub main a container holding the code the uses enters? If so, why is it that when a form button is used it is full? But here a VB default unused and empty? Seems to me with no event values it should not be there....?????
Parenthesis are required when they are required, and optional when they are optional. In the case of empty parameter/argument lists parenthesis are "just for show".
A Sub Procedure can be declared as Sub Main() or Sub Main - the parenthesis are optional when there are no parameters. Likewise, procedures/functions can be invoked without parenthesis if (and only if) no arguments are supplied.
Sub A ' ok, no parameter list - no need for parenthesis
Sub A() ' it's fine to use parenthesis anyway
Sub B(x as Integer) ' need parenthesis for parameter list
obj.A ' ok, no arguments - no need for parenthesis
obj.A() ' it's fine to use parenthesis anyway
obj.B(42) ' need parenthesis when arguments are specified
In the above, the definitions of A and invocations of A are equivalent as the parenthesis are optional in these cases.
When calling a method you do have a choice in VB whether you want to include the parentheses if there are no parameters. The same holds true for the definition of a method, be it a function or a sub.
See http://msdn.microsoft.com/en-us/library/dz1z94ha.aspx (Sub Statement on MSDN).
Calling a Sub Procedure
You call a Sub procedure by using the procedure name in a statement
and then following that name with its argument list in parentheses.
You can omit the parentheses only if you don't supply any arguments.
However, your code is more readable if you always include the
parentheses.
If I write this in the VBA editor:
Dim ws As Worksheet: set ws = ActiveSheet
ws.Columns(
IntelliSense shows me a seemingly unrelated tooltip:
_Default([RowIndex], [ColumnIndex])
The Worksheet.Columns property only accepts the index (column) number as far as I can see in the documentation.
So why am I asked for a RowIndex? Why does it refers to _Default (and what is it)?
The Worksheet.Columns property only accepts the index (column) number as far as I can see in the documentation.
Nowhere in the documentation does it say the Columns property takes a parameter, and indeed, it would be wrong to mention that, because it doesn't have any:
Like Worksheet.Rows, Worksheet.Columns yields a Range object. So when you "parameterize" it, what's really happening is this:
Set foo = ws.Columns.[_Default](value)
Any argument you provide, get interpreted as arguments to an implicit default member call against the Range object that was returned by the call to Columns.
You may have read somewhere that the default member of a Range is its Value - and that is not true. The default member of a Range is a hidden property named [_Default] (square brackets are required in VBA if you want to invoke it explicitly, because no legal VBA identifier can begin with an underscore), that takes two optional parameters:
When you read ("get") this default property without providing any arguments, this default property does get you the Range.Value (i.e. a single Variant value for a single cell, or a 2D Variant array for multiple cells). When you assign to this default property, you are assigning the Range.Value.
But when any arguments are provided when reading ("get") this default property, what you get is a call to the very standard Range.Item indexer property:
So what Columns does, is simply take your input range, and yield a Range object laid out in such a way that it can be accessed using a RowIndex argument - we can prove this using named arguments, which show that this code is illegal:
?Sheet1.Range("A1:C1").Columns.Item(ColumnIndex:=2).Address
>> "wrong number of arguments"
As is this equivalent code:
?Sheet1.Range("A1:C1").Columns(ColumnIndex:=2).Address
>> "error 1004"
Note that the _Default property yields a Variant, so the above .Address member call can only be resolved at run-time (and you don't get any intellisense for it, and the compiler will not flinch at any typo, even with Option Explicit specified - you will get error 438 at run-time though).
Best stick to safe early-bound land, and pull the returned object reference into a local variable:
Dim foo As Range
Set foo = ws.Columns(1)
Debug.Print foo.Address '<~ early-bound w/intellisense & compile-time validation
TL;DR: You're being prompted for a RowIndex argument because you are making a call (albeit an implicit one) to a hidden _Default property that accepts a RowIndex argument.
Access 2013
I'm calling a formula to modify a string and it's changing the values w/in the parent sub.
Example:
Debug.Print Str 'Hello World my name is bob
BOBexists = InStringChceck(Str,"bob")
Debug.Print Str 'HELLO WORLD MY NAME IS BOB
Debug.Print BOBexists 'TRUE
I've used this function, InStringCheck, in Excel VBA before (and it's just an example, all of my string tools are doing this same thing now and I don't know why)
Function InStringCheck(Phrase as string, Term as string) as Boolean
Phrase = UCase(Phrase)
Term = UCase(Term)
if instr(1, Phrase, Term) then InStringCheck = True else InStringCheck = False
end function
In several of my functions I manipulate the input variables, to arrive at a solution, but I don't want those manipulations to persist outside of the function unless I pass them back up - some how they're being passed up, but they're not dimed as public variables
VBA parameters are implicitly passed by reference (ByRef). This means you're passing a reference to the value, not the value itself: mutating that value inside the procedure will result in that mutated value being visible to the calling code.
This is often used as a trick to return multiple values from a function/procedure:
Public Sub DoSomething(ByVal inValue1 As Integer, ByRef outResult1 As Integer, ...)
You have two options:
Pass the parameters by value (ByVal)
Introduce local variables and mutate them instead of mutating the paramters (and heck, pass the parameters ByRef explicitly)
If you have lots of occurrences of parameters being implicitly passed ByRef in your project, fixing them everywhere can easily get tedious. With Rubberduck you can easily locate all occurrences, navigate there, and apply appropriate fixes:
Disclaimer: I'm heavily involved in the Rubberduck project.
Building a little on #Sorcer's answer, VBA has default Sub/Functions parameters passing "by reference" (i. e.: "ByRef" keyword assumed if not specified) so that if you don't want their "inside" modifications survive outside them you have to explicitly type "ByVal" keyword before them in the arguments list.
But you have the option to avoid such modifications take place altoghether by using StrComp():
Function InStringCheck(Phrase as string, Term as string) as Boolean
InStringCheck = StrComp(Phrase, Term, vbTextCompare) = 0
End Function
Which could also lead you to avoid the use of InStringCheck() in favour of a direct use of StrComp() in your code
I am generating strings with the names of existing variables. I want to use the strings to create a variable set to the VALUE of the existing variable, but I can't figure out how to achieve this.
Put another way if this helps:
A calling routine sends strings "abc" "cde" etc... Each string is the first several characters of a path variable I've already set. I then append "path" to the passed string to create the full name of the existing variable (e.g., %abcpath%) Now I want to get the value of %abcpath% and put it into a variable I can use it in the current routine.
Thanks for any help.
Here is part of the code I have:
SET abcPath=c:\path_to_abc_dir
SET cdePath=c:\path_to_cde_dir
call :names abc cde ...
:names
For %%G in (%*) do (
set name=%%G
:: Append "path" to name from calling routine
set namepath=!name!path
echo "!namepath!"
:: 1st time through namepath is "abcPath"
:: How to now set a var to the VALUE of %abcPath% set above?
::these don't work:
set dirpath=%%namepath%%
set dirpath=!%%namepath%%!
set dirpath=!%namepath%%%amepath%%!
set dirpath=!!name!path:%dirpath%=%%dirpath%%!
::I want to do things with %dirpath% in this routine:
if not "!dirpath!"=="" (
cd !dirpath!
:: call subroutine to get the number of files in the directory
call :forhere
do other stuff with var dirpath ...
)
)
....
::these don't work:
set dirpath=%%namepath%%
^^........^^ Not a valid variable reference
set dirpath=!%%namepath%%!
^^........^^ Not a valid variable reference
set dirpath=!%namepath%%%amepath%%!
^........^ This has been parsed at start and has no value
set dirpath=!!name!path:%dirpath%=%%dirpath%%!
^^ ^..........................^ two "variables" start and end
Delayed expasion over a value obtained with delayed expansion does not have a obvious syntax, because this does not exist. It can not directly be done and other commands need to be used
....
set "name=%%G"
set "namepath=%%Gpath"
call set "dirpath=%%!namepath!%%"
echo !dirpath!
....
Why or how does it work?
When the line is parsed, the only variable referenced is namepath with delayed expansion. The double percent signs are a escaped percent sign. So the line is translated into
call set "dirpath=%abcpath%"
Now, the call is executed, generating a second parse of the line, obtaining the correct value
This can also be done as
for %%a in ("!namepath!") do set "dirpath=!%%~a!"
In this case, the value inside namepath variable is stored into the for replaceable parameter and used to obtain the value to assign to the dirpath variable
In both cases, two "parse" (in the logic sense) operations are done.
In the first solution the first parse extracts the value of namepath and the second parse (invoked by call command execution) uses this value as a variable name.
In the second solution, we first get the value inside namepath (first "parse") and then this value is used in a new delayed expansion operation to retrieve the value to assign to dirpath
Excel workbooks have a CustomDocumentProperties collection. This collection is of type DocumentProperties and has an Add method that I'm attempting to call from MATLAB.
If I call the invoke method on the collection I see:
>> workbook.CustomDocumentProperties.invoke
Item = handle Item(handle, Variant, int32)
Add = handle Add(handle, string, bool, int32, Variant(Optional))
I assume this means the Add method requires a string, boolean, int32, and an optional variant, and this matches with the Microsoft documentation for the Add method.
However, all combination of inputs I've tried to this function result in an error. For example:
workbook.CustomDocumentProperties.Add('MyProp', true, int32(1), true);
Results in the error:
Invoke Error: Incorrect number of arguments
If I supply 7 or more arguments then I get the error:
Error: Invalid number is arguments. This method can take maximum 6 arguments
If I supply anything other than a string as the first argument I get the error:
No method 'Add' with matching signature found for class 'Interface.2DF8D04D_5BFA_101B_BDE5_00AA0044DE52'.
Has anyone successfully used this function to add a custom property to an Excel workbook from MATLAB?