I am trying to use the Excel advanced filter through PowerShell, but I am not having any luck. I can use an autofilter successfully by running the following code:
$rangetofilter = $worksheet2.usedrange.select
$excel.selection.autofilter(2, "TestFilter")
However, I don't understand how to properly convert the syntax given in Range.AdvancedFilter Method to something that PowerShell will accept. For example, I've tried
$excel.selection.AdvancedFilter("xlFilterInPlace", "", "", "TRUE")
But I get the following error:
Exception calling "AdvancedFilter" with "4" argument(s): "AdvancedFilter method of
Range class failed"
At line:1 char:32
+ $excel.selection.AdvancedFilter <<<< ("xlFilterInPlace","","","TRUE")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
So is there a way to run an Excel advanced filter through PowerShell?
I found this: Delete duplicate rows in excel using advanced filter, but it is not working either...
None of the arguments to AdvancedFilter() is a string.
Object AdvancedFilter(
XlFilterAction Action,
Object CriteriaRange,
Object CopyToRange,
Object Unique
)
The first is an enumeration. In VBA you can use those directly because there they are implicitly global. Not so in Powershell, where you have to reference them explicitly by their fully qualified names:
$xlFilterInPlace = [Microsoft.Office.Interop.Excel.XlFilterAction]::xlFilterInPlace
The other three arguments are typed as Object, which means they are of Variant type in COM. However, #2 and #3 are supposed to be Range objects, all bets are off if you pass in something else.
They are also marked as optional. Optional parameters that should have no value are represented by the Missing type in .NET COM Interop. Again, in Powershell you have to reference it explicitly:
$missing = [Type]::Missing
Argument #4 is supposed to be a Boolean, so just pass a Powershell bool constant (or, since this parameter is optional as well, $missing).
$excel.Selection.AdvancedFilter($xlFilterInPlace, $missing, $missing, $TRUE)
Related
I am having the worst luck with this line of code...
$Myexcel.visible = $true
$Myworkbook = $Myexcel.workbooks.add()
$Sheet1 = $Myworkbook.worksheets.item(1)
$Sheet1.name = "Summary"
$Sheet1.Cells.item(3, 3) = '=IF(B3>0,ROUND((B3/B16)*100),"N/A")&"%"'
Things I've tried:
Shifting/replacing all of the single quotes and double quotes in every configuration you can think of,
escaping all the special characters including the parentheses, the asterisks, the commas, the gt symbol, the percentage symbol, and the configurations of quotes,
and adjusting the scope of the cell (i.e. trying different cells, using a range instead of an item)
I had to make an account just to see if I could get some help on this one, I've spent way too much time trying to get it to work.
tl;dr
The error message isn't very helpful, and seems to be a pretty generic one that is given in a number of situations, but in your case the root cause is the ROUND function takes 2 arguments and you've only specified one.
Try this instead:
$Sheet1.Cells.item(3, 3) = '=IF(B3>0,ROUND((B3/B16)*100,2),"N/A")&"%"'
# add an argument here ^^
Long Version
I initially thought the problem was something to do with the .items part of your sample $Sheet1.Cells.item(3, 3) - I'm more familiar with just using $Sheet1.Cells(3, 3), but they both give the same error, as do the following attempts:
PS> $Sheet1.Cells.item(3, 3) = '=IF(B3>0,ROUND((B3/B16)*100),"N/A")&"%"'
OperationStopped: 0x800A03EC
PS> $Sheet1.Cells(3, 3) = '=IF(B3>0,ROUND((B3/B16)*100),"N/A")&"%"'
OperationStopped: 0x800A03EC
PS> $Sheet1.Cells(3, 3).Formula = '=IF(B3>0,ROUND((B3/B16)*100),"N/A")&"%"'
OperationStopped: 0x800A03EC
So as an experiment I tried manually pasting the formula into a new sheet and got this:
Microsoft Excel
You've entered too few arguments for this function.
[ Ok ]
Your root problem is the ROUND function takes 2 arguments - the value and the precision:
https://support.microsoft.com/en-us/office/round-function-c018c5d8-40fb-4053-90b1-b3e7f61a213c#:~:text=The%20ROUND%20function%20rounds%20a,of%20this%20function%20is%2023.78.
Syntax
ROUND(number, num_digits)
The ROUND function syntax has the following arguments:
number Required. The number that you want to round.
num_digits Required. The number of digits to which you want to round the number argument.
If you change your formula to, e.g.
=IF(B3>0,ROUND((B3/B16)*100,2),"N/A")&"%”
it should work fine.
In Data Flow task I am trying to replace * with Data Flow component "Derived Column" using the following expression:
REPLACE(Code, "*", " ") - but this simple replace statement will not work, I have also tried to cast "Code" as DT_WSTR, but no help so far. Hopefully someone know how to do it. "Code" value is coming from excel source and data type for it is DT_R8
Error at Data Flow Task [Derived Column 1 [57]]: The function
"REPLACE" does not support the data type "DT_R8" for parameter number
1. The type of the parameter could not be implicitly cast into a compatible type for the function. To perform this operation, the
operand needs to be explicitly cast with a cast operator.
I need to do a case insensitive search in an Excel document using Range.Find.
I'm currently using the following command as an attempt do a case insensitive search for any email address returned by https://haveibeenpwned.com
$Found = $WorkSheet.Cells.Find($SearchText, $null, "xlValues", "xlWhole", "xlByRows", 1, $false) #What, After, Lookin, LookAt, SearchOrder, MatchCase
It returns:
WARNING: [] No public exploits found!
Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))
At C:\Users\qqqq\Documents\incidents\Search-PwnAddress.ps1:31 char:9
+ $Found = $WorkSheet.Cells.Find($SearchText, $null, "xlValues" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
How do I properly do a Range Find so that I can do a case insensitive search?
From Range.Find - note that xlValues, xlWhole, and xlByRows are not referred to as Strings, but constants. They are members of specific Enumerations - the XlFindLookIn, XlLookAt and XlSearchOrder enumerations.
Enumerations have members with descriptive names that reference a specific value - so in this case, you can use the corresponding value as your argument. Trying to pass their names as Strings - i.e. "xlValues" - will throw a "Type Mismatch" error.
xlValues: -4163
xlWhole: 1
xlByRows: 1
Note also that you should use [Type]::Missing instead of $null, as this answer suggests.
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?
Thanks in Advance!
Here is the code:I want to gather the value of the below variable...
$Sheet3.Cells.Item($intRowDisk, 4) = $objItem.Size/1024/1024/1024 - $objItem.FreeSpace/1024/1024/1024
Then I want to compare that value and if it is larger than 100 GB place a value of yes or no in a column within an excel spreadsheet.
if ( $Sheet3.Cells.Item($intRowDisk, 4) -gt 100 ) {
$Sheet1.Cells.Item($intRow, 12) = write "Yes"
But I get the error of : ERROR: Bad argument to operator '-gt': Could not compare "System.__ComObject" to "100". Error: "Cannot convert the "100" value of type "System.Int32" to type "System.
ERROR: __ComObject".".
IME_InventoryV1.8.ps1 (124): ERROR: At Line: 124 char: 49
ERROR: + if ( $Sheet3.Cells.Item($intRowDisk, 4) -gt <<<< 100 ) {
ERROR: + CategoryInfo : InvalidOperation: (:) [], RuntimeException
ERROR: + FullyQualifiedErrorId : BadOperatorArgument
Why do you have write "Yes" inside your if block? Does simply assigning "Yes" not work?
write is an alias for the Write-Object cmdlet, which puts content on the pipeline for the next command. It probably isn't what you want to use in this case. Try just assigning the string "Yes" and see if that solves your issue.
Also, on your comparison - while not particularly helpful, PowerShell is telling you that you can't compare a COM object and the value 100. You need to include a call to actually get the value out of the COM object for comparison by including the method invocation Value() at the end of your expression:
$Sheet3.Cells.Item($intRowDisk, 4).Value()
I figured it out. I had to add a variable and then feed the variable to the if statement. It now works like a charm.
$Sheet3.Cells.Item($intRowDisk, 4) = $objItem.Size/1024/1024/1024 - $objItem.FreeSpace/1024/1024/1024
$valueforif = $objItem.Size/1024/1024/1024 - $objItem.FreeSpace/1024/1024/1024
if ( $valueforif -gt 100 )
{
$Sheet1.Cells.Item($intRow, 12) = "Yes"
}