Using Powershell 2.0 I am trying to copy the results of a formula in one worksheet to another. In order to do this I need to use paste special (otherwise I get #value error).
However, the following code is not working. The first block is just a regular paste that works fine, but the second block has the paste special and it doesn't work. The error I get is below.
The question does anyone know what this error means or what the best way to do a paste special using Powershell and Excel is?
Works:
$worksheet.activate()
$sessionidcopyrange = $worksheet.Range("J1").EntireColumn
$sessionidcopyrange.copy()
$worksheet2.activate()
$sessionidpasterange =$worksheet2.Range("A1")
$worksheet2.paste($sessionidpasterange, $false)
Doesn't work:
$worksheet.activate()
$codecopyrange = $worksheet.Range("Q1").EntireColumn
$codecopyrange.copy()
$worksheet2.activate()
$codepasterange = $worksheet2.Range("B1")
$worksheet2.pastespecial(-4163, $false)
Exception calling "PasteSpecial" with "2" argument(s): "PasteSpecial method of
Worksheet class failed"
At line:33 char:25
+ $worksheet2.pastespecial <<<< (-4163, $false)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
Example:
$Dest = $Excel.Workbooks.Add()
$Dest.ActiveSheet.Range("B:C").copy()
$Dest.ActiveSheet.Range("D1").Select()
$Dest.ActiveSheet.Range("D1").PasteSpecial(-4163)
Paste special with PowerShell and Excel:
The second value is of type XlPasteSpecialOperation.
$worksheet2.pastespecial(-4163, $false)
should be
$worksheet2.pastespecial(-4163, xlPasteSpecialOperationNone)
Related
I am getting error while enabling autofiltermode using powershell on excel file. This is the script i am trying
$objExcel=New-Object -ComObject Excel.Application
$objExcel.Visible=$True
$workbook=$objExcel.Workbooks.Open('C:\Trash\filter.xlsx')
$worksheet = $workbook.worksheets | where {$_.name -eq 'sheet1'}
$worksheet.autofiltermode=$true
$workbook.Save()
$objExcel.Quit()
Error:
Unable to set the AutoFilterMode property of the Worksheet class
At line:1 char:1
+ $worksheet.autofiltermode=$true
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
This is what i am expecting(attachment)
[1]: https://i.stack.imgur.com/X0DS8.png
FYI:
Worksheet.AutoFilterMode Property
Remarks
You can set this property to false to disable filtering (that is, to remove the filter drop-down arrows), but you cannot set it to true. To enable filtering and create a filtered list, use the AutoFilter method of a Range object, or use the AutoFilter method of a NamedRange object.
I am trying to perform arithmetic on an existing excel sheet that has figures in it. My code:
$Excel = New-Object -ComObject Excel.Application
$ExcelWorkBook = $Excel.Workbooks.Open($temp)
$ExcelWorkSheet = $Excel.WorkSheets.item(1)
$ExcelWorkSheet.activate()
$Prehit = $ExcelWorkSheet.Cells.Item(2,1)
$Hit1 = $ExcelWorkSheet.Cells.Item(2,2)
$Hit2 = $ExcelWorkSheet.Cells.Item(2,3)
$Hit3 = $ExcelWorkSheet.Cells.Item(2,4)
$Remain = 0
If ($hit -eq 1) {
$Remain = $Prehit - $Hit1
}
If ($hit -eq 2) {
$Remain = $Prehit - $Hit1- $Hit2
}
Yields the following error:
Method invocation failed because [System.__ComObject] does not contain a method named 'op_Subtraction'.
At C:\path_to_ps1_file.ps1:40 char:3
+ $Remain = $Prehit - $Hit1- $Hit2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (op_Subtraction:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
I have tried casting all the variables as ints yet that yields the same error. I even casted the numbers as ints in the powershell modules used to create this excel file. What am I missing?
I realize now I was referencing the cell values incorrectly. The correct way is to do:
$Prehit = $ExcelWorkSheet.Cells.Item(2,1).Text
$Hit1 = $ExcelWorkSheet.Cells.Item(2,2).Text
$Hit2 = $ExcelWorkSheet.Cells.Item(2,3).Text
$Hit3 = $ExcelWorkSheet.Cells.Item(2,4).Text
Whenever I've run into this sort of thing, I just the 'Excel Marco Recorder' and review the VBA code it produces and then convert that to PowerShell for later automation use cases.
Yet at no point in the code you posted are you making the XLS visible for you to act on it.
For example:
# Instantiate Excel instnace
$excel_test = New-Object -ComObject Excel.Application
# Make the instance visiable to work with it
$excel_test.visible = $true
# Catch alerts
$excel_test.DisplayAlerts = $true
# Add in the file source
$excel_test.Workbooks.Add('D:\Temp\Test.xlsx')
# Choose a sheet in the workbook
$Sheet = $excel_test.Worksheets.Item(1)
# Assign a formula to the target variable
$strFormula = '=(SUM(A1:C3)/3) - 1'
# Assign the formula to the target variable
$Sheet.Cells.Item(4,4) = $strFormula
$SourcecellCell = ($Sheet.Cells.Item(4,4)).Value2
$NewCell = 3
$sheet.Cells.Item(5,5) = $SourcecellCell - $NewCell
# Exit the XLS without saving
$excel_test.Quit()
Whenever I've run into this sort of thing, I just the 'Excel Marco Recorder' and review the VBA code it produces and then convert that to PowerShell for later automation use cases.
Yet at no point in the code you posted are you making the XLS visible for you to act on it. Since it is not visible, you cannot perform UI actions on it.
Secondly, this...
$excel_test.Worksheets.Item(2).Cells.Item(2,2).Formula() = $strFormula
... is where your issues begin. If you step through this one step at a time, you'll immediately see the aforementioned will simply fail.
For example:
# Instantiate Excel instance
$excel_test = New-Object -ComObject Excel.Application
# Make the instance visible to work with it
$excel_test.visible = $true
# Catch alerts
$excel_test.DisplayAlerts = $true
# Add in the file source
$excel_test.Workbooks.Add('D:\Temp\Test.xlsx')
# Results
<#
Application : Microsoft.Office.Interop.Excel.ApplicationClass
Creator : 1480803660
Parent : Microsoft.Office.Interop.Excel.ApplicationClass
...
#>
# Assign a formula to the target variable
$strFormula = "=((A1:C4/10000)-1)"
# Assign the formula to the target variable
$excel_test.Worksheets.Item(2).Cells.Item(2,2).Formula() = $strFormula
<#
Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))
At line:1 char:1
+ $excel_test.Worksheets.Item(2).Cells.Item(2,2).Formula() = $strFormul ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
#>
$Error | Format-List -Force
<#
Exception : System.Management.Automation.RuntimeException: The variable '$command' cannot be retrieved because it has not been set.
at System.Management.Automation.VariableOps.GetVariableValue(VariablePath variablePath, ExecutionContext executionContext,
VariableExpressionAst varAst)
at Prompt(Closure , FunctionContext )
TargetObject : command
CategoryInfo : InvalidOperation: (command:String) [], RuntimeException
FullyQualifiedErrorId : VariableIsUndefined
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at Prompt, C:\Users\Daniel\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1: line 55
at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
PSMessageDetails :
...
#>
I am working on adding links to a spreadsheet of variable length through PowerShell and I am running into an error no matter how I do it. This is the loop I am currently trying to make work, which is nested within an excel comobject, with $sheet representing $excel.activeworkbook.activesheet :
$v = 2
foreach($i in $list){
$r = "A"+$v
$link = "www.url.com"
$sheet.Hyperlinks.Add($r,$link)
$v++
}
Which keeps throwing the following error:
Exception setting "Add": Cannot convert the "A2" value of type "string" to type "Object".
At C:\hyperlink_wip.ps1:31 char:5
+ $sheet.Hyperlinks.Add($r,$link)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : RuntimeException
in this example, $list is a list which contains the information from one column of this spreadsheet and will always be the same length as the spreadsheet itself. The spreadsheet also has a header row, so the cells I want to hyperlink start at A2. I also tried the method outlined here for adding links to an excel spreadsheet but got an incorrect format error each time I tried it.
$r isn't a Range or Shape. Here's the Add Method on MSDN
Here's an example of how you could use it in your code:
$v = 2
foreach($i in $list){
$r = $sheet.range("A"+$v)
$link = "www.url.com"
$sheet.Hyperlinks.Add($r,$link)
$v++
}
I have a VLOOKUP being inserted into my spreadsheet's F column like this:
$vLookup = "=VLOOKUP($refCol,'$xlsLocsDIR[locs.xlsx]Device'!`$B`$2:`$C$rowsDvcs,2,FALSE)"
$sheetSave.Cells.Item(2,6).Formula = $vLookup
Which is, to be clear, saved properly in Excel like this:
=VLOOKUP(E2,'[locs.xlsx]Device'!$B$2:$C24549,2,FALSE)
(There are ~25k lines in the reference file, but there are over 200k in the file I have the VLOOKUP in.)
Because of the size of the file in which I'm doing the VLOOKUP within, and the customer could be utilizing 32-bit OS or Excel, I have to Copy/Paste no more than around 30000 rows at a time, to fill all 200k rows out, like so:
#32-bit OS/Excel app compatibility
#Excel/32-bit OS/memory errors occur if doing more than 30k cells
#instead, we do 20k, save, 20k, save, etc
for ($i=2; $i -le $rowsTrans; ($i+30000))
{
#set the stop point, not to exceed total usedrows
if (($i + 30000) -gt $totalRows)
{$j = $totalRows}
else
{$j = ($i+30000)}
#copy the data
$copyCell = (("F" + $i))
$copyRange = $sheetTrans.Range($copyCell)
$copyRange.Copy() | Out-Null
$sheetSave.Activate()
$pasteRange = $sheetTrans.Range(("F"+$i+":F"+$j)).Select()
$sheetSave.PasteSpecial(7)
$fileWorking.Save()
}
I only want to copy the VLOOKUP formula from Cell F2, into the next 20k rows of column F, then save the file, and iterate through again until I've populated the entire file.
When I do the above, and I've tried different methods aside from this example, I always receive a MethodInvocation Error, unless I explicitly make the file/sheet visible, like so, before the above loop:
$xlsObject.Visible = $true
What am I misunderstanding about the Copy() / PasteSpecial() function calls? Why does the sheet have to be visible?
NOTE: I've tried to anonymize the above code and limit what is necessary to understand the issue. The code functions, I just don't want to require the Excel instance to be brought into view at any point. I'd prefer the script run invisible to the end-user.
The MethodInvocation error I receive is typically as follows:
Exception calling "PasteSpecial" with "1" argument(s): "PasteSpecial method of
Worksheet class failed"
At line:1 char:25
+ $sheetTrans.PasteSpecial <<<< (9)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
I was able to solve this by doing a few direct references, and changing the way I assigned the range, and then calling PasteSpecial, like so:
$pasteRange = $sheetTrans.Range(("F"+$i+":F"+$j))
$pasteRange.PasteSpecial($xlPasteValues) | Out-Null
With declarations like this:
Add-Type -ASSEMBLY "Microsoft.Office.Interop.Excel" | out-null
$global:xlPasteFormulas = -4123
$global:xlPasteValues = -4163
I have created a Powershell script to filter out a particular item in an coulmn . The script so far :
$file1 = "C:\Users\ab270510\Desktop\t.xlsx" # source's fullpath
$xl = new-object -c excel.application
$xl.displayAlerts = $false # don't prompt the user
$wb1 = $xl.workbooks.open($file1) # open target
$sh1 = $wb1.sheets.item('Sheet1') # sheet in workbook
$sh1.Select()
$sh1.Range("C1").Select()
$xlFilterValues = 7 # found in MS documentation
$filterList = “Jan”,”feb” # array
$xl.Selection.AutoFilter(2, $filterList ,$xlFilterValues)
$sh1.cells.Item.EntireColumn.AutoFit
$wb1.close($true) # close and save workbook
$xl.quit()
But the above code is giving error like :
Exception calling "AutoFilter" with "3" argument(s): "AutoFilter method of Range class failed"
At line:1 char:25
+ $xl.Selection.AutoFilter <<<< (2, $filterList ,$xlFilterValues)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
Please help me to write a Powershell script that will filter out only "Jan" & "Feb" item from a particular coulmn of an excel file . Also suggest me how can I filter single or multiple item .
Please see my answer here, after much reaserch i have figured this out, and it works.. Howerver, i am still working on how to do the reverse and only not choose a few items...Have to give credit to the above post... But i have tested and it works great...
Here is the working code, and a link to the thread...
# Filter for an array of values IE: choose muipliple items.... in one column
$xlFilterValues = 7 # found in MS documentation
$FL = #("value 1", "value2")
$rng=$Worksheet.cells.item(2,38).entirecolumn
$rng.select | Out-Null
$excel.Selection.AutoFilter(20,$FL,$xlFilterValues)
http://social.msdn.microsoft.com/Forums/office/en-US/81e4a2b0-d016-4a56-92e6-c3d4befa75db/powershell-excel-autofilter-on-multiple-items?forum=exceldev