I am trying to set a value to an excel cell through Powershell, and I am getting the error HRESULT: 0x800A03EC, which ends the script prematurely. I realize there have been other questions relating to this error or similar, but none of the solutions have worked for me, so I am assuming this is a separate problem.
I have run my script before but it is only now giving me this error.
Relevant code:
$Output_Location = "Z:\Documents\Powershell"
$Excel_File = "Report.xlsx"
$ExcelWorkBook = $Excel.Workbooks.open("$Output_Location\$Excel_File")
$MainSheet = $ExcelWorkBook.worksheets.Item("Report")
$Sheet1 = $ExcelWorkBook.worksheets.Item("Sheet1")
$Sheet1.name = "Statistics"
$StatisticsSheet = $ExcelWorkBook.worksheets.Item("Statistics")
$row = 3
$column = 2
$StatisticsSheet.Cells.Item(2,2)= 'KeyToMatch'
$StatisticsSheet.Cells.Item($row,$column) = '=COUNTIFS(Report!E2:E200000,B$3,Report!G2:G200000,"UserMailbox")'
$row++
$StatisticsSheet.Cells.Item($row,$column) = '=COUNTIFS(Report!E2:E200000,B$3,Report!G2:G200000,"RemoteUserMailbox")'
$row++
The code loads up the excel file and hits the line which sets the cell (2,2)/(B,2) to its value just fine. But when the code hits the line setting the cell value the row below the KeyToMatch (B,3), it throws the error 0x800A03EC.
Full error:
Exception from HRESULT: 0x800A03EC
At Z:\Documents\Powershell\Reporting\Report.ps1:113 char:1
+ $StatisticsSheet.Cells.Item($row,$column).value = '=COUNTIFS(Report! ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
I have tried spacing out the '=' between the cell and value, I have also tried the following:
$StatisticsSheet.Cells.Item($row,$column).value = ...
$StatisticsSheet.Cells.Item($row,$column).value2 = ...
$StatisticsSheet.Cells.Item($row,$column).text = ...
$StatisticsSheet.Cells.Item($row,$column).formula = ...
I can comment out any number of lines which set the cell's value to a formula and the first one to attempt to do so will throw the mentioned error.
Like I said, I have run this script before but it is only now giving me troubles. How can I fix this so the code runs smoothly?
Moved solution from question to answer:
RESOLUTION:
To resolve this issue, in the text I assigned to the cell, I replaced single quotes with double quotes, and because of this, had to escape the '$' and ' " ' characters. I also ADDED single quotes around "Report" (The table name from which data is being pulled) each time it came up within the text.
It ended up looking like this, and running fine:
$StatisticsSheet.Cells.Item($row,$column) = "=COUNTIFS('Report'!E2:E200000,B`$3,'Report'!G2:G200000,`"UserMailbox`")"
Still not sure why this error occurred-the code had worked every week prior to this! Before changing the script and finding the resolution, I tested it on multiple machines (5+) and it threw the error mentioned in the title every single time.
this is very simple issue, which in range put the values like
ExcelSheet.Cells.Range("A1:A1").Value = "'asdf"
Related
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
Following up from this question, I'm trying to replace $B$1 to TEXT($B$1,"0000") on all formulas I can find on a lot of workbooks. Now that i'm past that .save() problem, I've got another (which should've been the first, actually): I can't seem to change .Formula value, no matter what I try.
PS C:\> $Search.Formula = $Search.Formula -replace '\$B\$1','TEXTO($B$1,"0000")'
Exceção ao definir "Formula": "Exceção de HRESULT: 0x800A03EC"
No linha:1 caractere:1
+ $Search.Formula = $Search.Formula -replace '\$B\$1','TEXTO($B$1,"0000")'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : CatchFromBaseAdapterSetValueTI
Formula is:
=PROCV(("A"&ANO($A6)&"M"&MÊS($A6)&"P"&$B$1);BASE!$A:$P;9;FALSO)
In English, if I remember the correlation correctly:
=VLOOKUP(("A"&YEAR($A6)&"M"&MONTH($A6)&"P"&$B$1);BASE!$A:$P;9;FALSE)
The expected output would be
=VLOOKUP(("A"&YEAR($A6)&"M"&MONTH($A6)&"P"&TEXT($B$1,"0000"));BASE!$A:$P;9;FALSE)
There were a couple of things going on with what you supplied. At first glance, you seem to be using the backslash for an escape character to make the dollar signs literal. The escape character for this in PowerShell is the back-tick or grave (e.g. `).
If I was performing this action within Excel, I would probably just Find & Replace every $B$1 on the worksheet with text($B$1, "0000"). Seems to me that it is powerful enough to take care of the operation without PowerShell's -replace method. The worksheet method does depend somewhat on $B$1 begin available but since it is also in the replacement, you pretty much need to know what you are replacing beforehand. Some error control in that area may be necessary if this script is left for casual users.
$excel = New-Object -comobject Excel.Application
$FilePath = "c:\temp\example.xlsx"
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $true
$worksheet = $workbook.worksheets.item("Sheet1")
#set some Find & Replace vars
$what = "`$B`$1"
$with = "text(`$B`$1, `"0000`")"
#use worksheet-wide Find & Replace to change formula
$worksheet.usedrange.replace($what, $with, 2)
#formula(s) should be changed. now Find it and display it
$fnd = $worksheet.usedrange.find($what, $worksheet.range("A1"), -4123, 2)
Write-Output $fnd.formula
$workbook.save()
$workbook.close()
$excel.quit()
I've proofed the Range.Replace method by finding and displaying the formula after the operations and made more extensive use of the grave escape character rather than swap back and forth between single quotes and double quotes within quoted strings.
The above code uses the EN-US version I tested with. The actual replacement text for your regional settings would seem to be,
$with = "texto(`$B`$1; `"0000`")"
I have scoured the web and this site looking for an answer on this, so I would really appreciate some help.
I'm creating a VBScript to do some modifications to a user-specified Excel spreadsheet. I have the first part of my script working fine, but the second part is driving me nuts. I need it to search the first column for a value and, if found, delete the row. Right now I'm not worrying about the deletion statement--I'm doing testing by seeing if I can get the For Each statement to run properly as well as the If Then statement. Here's the specific block of code:
For Each cell in objSheet.Columns("A:A").Cells
Set cell = objSheet.Columns("A:A").Cells
If cell.Value = "60802400040000" then
cell.font.bold = True
End If
Next
I have tried many variations of this and cannot find the right combination. Initially I was getting an "Object Required" messages, and after reading a number of posts, found that I needed to put in a Set statement for cell, which I did. Now I am getting a Mismatch Type error message.
The funny thing is, before I put in the Set statement, the code would execute, but it would throw the Object Required error when I closed the spreadsheet. After adding it, the error for the Type Mismatch pops up immediately.
Most examples I keep finding on the web are for VBA, and I try to modify them for VBS, which I don't know very well. Any assistance anyone can give me will be greatly appreciated.
You are redefining cell, cell is defined automatically in the For Each statement.
Delete this line
Set cell = objSheet.Columns("A:A").Cells
This is an example from Help, unfortunately Help doesn't have any examples that uses For Each, only For x = n to n and other means. For Each is the right thing to do.
Set r = Range("myRange")
For n = 1 To r.Rows.Count
If r.Cells(n, 1) = r.Cells(n + 1, 1) Then
MsgBox "Duplicate data in " & r.Cells(n + 1, 1).Address
End If
Next n
For vba to vbs, you have to create the object and use, as some objects are automatically available in VBA (like app object) - Set exceldoc = CreateObject("c:\blah\blah.xls) then to use Set r = exceldoc.worksheets(0).range("MyRange").
Also you have to use constant values not names as vbscript can't look them up.
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)