powershell Empty value override by other value excel - excel

I have this problem where i have 2 files and the output are:
value from file A is "No data"
value from file B is "prior to versions 0.9.8zd"
when I tried to write it on excel cell using powershell, value B always override value A. How to prevent this?
$outlook = new-object -comobject outlook.application
$dir="c:\users\john\desktop\"
$msgs=get-childitem $dir -filter "*.msg"
$rgx="blabla"
$regex="blablabla"
$xl=New-Object -ComObject Excel.Application
$xl.visible=$true
$wkbk=$xl.workbooks.add()
$wkbk.worksheets.add()
$wksht=$workbook.worksheets.item(1)
$wksht.name="TEST"
$wksht.cells.item(1,11)="Version(s)"
foreach($msg in $msgs)
{
$msg=$outlook.CreateitemFromTemplate($dir+$msg)
$body=$msg.body
if($body -match $rgx)
{
#echo "true"
$version=$body|select-string -pattern $regex -allmatches |%{$_.matches}|%{$_.value}
}
$row=$wksht.usedrange.rows.count+1
$usedrange=$wksht.usedrange
$usedrange.entirecolumn.autofit()|out-null
if([string]::IsNullOrEmpty($version))
{
$wksht.cells.item($row,11)="No data"
}
else
{
$wksht.cells.item($row,11)=$version
}
Expected result :
No Data <----first row,
prior to versions 0.9.8zd <-------2nd row
But what I got :
prior to versions 0.9.8zd <----first row,
prior to versions 0.9.8zd <-------2nd row
Your help highly appreciated. That's basically the whole code. do I missing something

Related

Finding if excel sheet contains array using powershell

I'm trying to find out if an excel sheet contains an array (in any cell in the fourth sheet). The variable is a user input as shown:
$j = Read-Host "Enter sensor serial number"
$Sens_name = #("$j")
And the act of it trying to find the input looks like this, where $EPRB2_loca is the location of the excel file including file extension:
#Checking in EPRB 2 file
$Excel = New-Object -ComObject Excel.Application
$Workbook = $Excel.Workbooks.Open("$EPRB2_loca")
$WorkSheet = $Workbook.Sheets.Item(4)
$WorkSheet.Name
$EPRB2_file = $WorkSheet.Cells.Find("$Sens_name")
if ($EPRB2_file.HasArray -eq $false)
{
$EPRB2_file = $null
}
Can someone please help me figure out why it won't show as it containing the array when I know it does?
I was using the wrong command.
If anyone comes across this, use .Count instead of .HasArray

Powershell -> find/replace in Excel -> look for a string in one cell and change the string in another cell

I would like to search for a string in a column. If it finds that string, I would like the script to replace the string in another cell - same row, different column. So my columns are like this...
screenshot
I want to search for "Hours" or "Hrs" in column "Unit Type" and when it finds it, I want to change the "Job ID" in that same row to 3289. Here's what I got so far and nothing seems to happen. Any help would be greatly appreciated. Thanks!
$excelFile = "C:\do\BEFORE.xls"
$objExcel = New-Object -ComObject Excel.Application
$WorkBook = $objExcel.Workbooks.Open($excelFile)
$worksheet = $WorkBook.sheets.item("Sheet1")
$rowCount = $worksheet.usedrange.rows.count
Select-Object "Acct", "Customer_Name", "Invoice","Inv_Date","Cost_ID","Job_ID","Description","Hours", "Quantity", "Price", "Unit_Type", "Amount"
foreach ($row in $excelFile) {
if ($row.Unit_Type -eq "Hours") {
$row.Job_ID = "3289"
}
}
$WorkBook.Save()
$WorkBook.Close()
The Select-Object command is not doing anything as you're not providing it any data. Though that doesn't matter much since you're dealing with an excel com object. You'll need to specify which column you're checking and I find it's easiest to use a for loop. We will start on row 2 since the first row is the headers. Based on your example the Unit Type column is 6 and the Job ID column is 1. You also wanted to check for either hours or hrs so a regex match would be an appropriate approach.
$excelFile = "C:\do\BEFORE.xls"
$objExcel = New-Object -ComObject Excel.Application
$WorkBook = $objExcel.Workbooks.Open($excelFile)
$worksheet = $WorkBook.sheets.item("Sheet1")
$rowCount = $worksheet.usedrange.rows.count
$unittypecolumn = 6
$jobidcolumn = 1
for($i = 2; $i -le $rowCount; $i++)
{
if($worksheet.Cells($i,$unittypecolumn).Value2 -match "hours|hrs")
{
$worksheet.Cells($i,$jobidcolumn).Value2 = "3289"
}
}
$WorkBook.Save()
$WorkBook.Close()

PowerShell Remove Newline Characters From Excel Cells

I have a script that allows me to iterate over every cell (even the unused ones), but when I set the text property of the cell to remove new lines with nothing, I get an error that I can't update all cells even though the script is only updating one cell at a time:
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $false
$workbook = $Excel.Workbooks.Open("D:\Excel\excel.xlxs")
$worksheet = $Workbook.Sheets.Item(1)
$allcells = $worksheet.UsedRange.Cells
$total = $allcells.columns.count
$everycell = $worksheet.Range("1:$total")
foreach ($cell in $everycell)
{
if ($cell.Text -ne "")
{
$cell.Text = $cell.Text.Replace("`r`n","")
}
}
$workbook.Save()
$excel.Quit()
To iterate over used cells within a range and remove characters from the cells (in this case a new line), is there a different way to replace all characters in all cells text equal to something else? The manual way of doing this would be to load Excel, and use control and h key to just replace. I would think there's a way to do this as well with the com object.
In my testing, $worksheet.Range("1:$total") was 49152 cells. Here is what I used to simplify removing newlines from each used cell.
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $false
$workbook = $Excel.Workbooks.Open("D:\Excel\excel.xlsx")
$worksheet = $Workbook.Sheets.Item(1)
$allcells = $worksheet.UsedRange.Cells
foreach($cell in $allcells)
{
$cell.value = $cell.value2 -replace '\r?\n'
}
$workbook.Save()
$excel.Quit()
Couple of things I wanted to point out. First, you have a typo in the excel filename, maybe that is just in this posting. Second, text is a read only field, you need to set value as shown.

Exception from HRESULT: 0x800A03EC (Trying to modify cell in Excel through PowerShell)

I just recently joined an IAM team, and this month had to send out hundreds of emails to people notifying them of an account expiration (they are asked to either request for an extension or termination of the account). Thankfully, there's already a script made to do that part, but for dealing with the responses there is not. There's an excel spreadsheet where I record what is to happen to each account. I was hoping to make a script that can go through each of the responses and mark in the desired field in the spreadsheet accordingly. I've been having trouble with the part of the script where I modify the value under the desired field for the user.
I'm fairly new to PowerShell, so I'm not sure what the issue is. I already spent a few hours looking online and found quite a few possible solutions, but none of them have worked for me. A common problem is apparently using an older excel file, but it's fresh and it's Excel 2016. Another one is not having the correct file type, but I checked and that's not it either. The line of code in question is $extend.Cells.Item($modifyCell.Cells.Row) = "$data".
Any ideas what the problem could be?
Code:
# Path to .msg files
$msgDir = "C:\Users\me\Desktop\Test"
# Array to store results
$msgArray = New-Object System.Collections.Generic.List[object]
# Loop throuch each .msg file
Get-ChildItem "$msgDir" -Filter *.msg |
ForEach-Object {
# Open .msg file
$outlook = New-Object -comobject outlook.application
$msg = $outlook.Session.OpenSharedItem($_.FullName)
# Add .msg file Subject and Body to array
$msgArray.Add([pscustomobject]#{Subject=$msg.Subject;Body=$msg.Body;})
$msg.Close(0) # Close doesn't always work, see KB2633737 -- restart ISE/PowerShell
}
# Loop though / parse each message
ForEach ($message in $msgArray) {
$subject = $message.subject
$body = $message.body
$regex = [regex] '\s*(\w*)\s*\|$'
If ($body -match $regex) {
$username = $body
}
$parse = $body | Select-String -Pattern "Please extend"
If ($parse -eq "Please extend") {
$data = "Y"
}
}
# Open Excel
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $True
$OpenFile = $Excel.Workbooks.Open("C:\Users\me\Desktop\test.xlsx")
$Workbook = $OpenFile.Worksheets
$Worksheet = $Workbook.Item(1)
# Get the values for each column
$samacctname = $Worksheet.Cells | where {$_.value2 -eq "SAM Account Name"} | select -First 1
$extend = $Worksheet.Cells | where {$_.value2 -eq "Extend"} | select -First 1
# Get the values for each row in SAM Account Name
$userValues = #()
for($i=2; $samacctname.Cells.Item($i).Value2 -ne $null; $i++ ){
$userValues += $samacctname.Cells.Item($i)
}
# Get the values where the cell value of SAM Account matches the username
$modifyCell = $userValues | where {$_.Value2 -eq $username}
# Modify the Extend cell using the username's row position
$extend.Cells.Item($modifyCell.Cells.Row) = "$data"
# Save the file
$OpenFile.Save()
Edit 1: I went back into my code and first tried to hard-code the data value I was trying to add to the cell, but I still got the same error. I then tried hard-coding it right when I call the line $extend.Cells.Item($modifyCell.Cells.Row) = "Y" and it works as it should. So how I'm trying to use regex to pull the username is likely not right. Probably how I'm pulling the data as well.

Can't insert formula referencing different worksheet using Powershell

For some reason, inserting formula into Excel table using Powershell script. If formula is entered manually, it works fine. Suppose I have 3 elements in $names array:
$excel = New-Object -ComObject excel.application
$excel.visible = $true
$workbook = $excel.Workbooks.Add()
$names = #()
foreach ($i in 1,2,3) {
$ws = $workbook.Worksheets.Add()
$names += $ws.Name
}
$i = 1
foreach ($sheet in $names) {
$formula = "=COUNT('$sheet'!D:D)"
write-host $formula
$excel.cells.item($i, 1).Formula = $formula
$i++
}
What happens: The first cell gets the correct value, but the formula name is missing (e.g. instead of =COUNT('Sheet2'!D:D) I get =('Sheet2'!D:D), and the other 2 throw 0x800A03EC exception. The sheet I reference definitely exists, because if I copy and paste values printed by write-host $formula manually, it works as expected.
It also seems to work correctly If I don't reference another sheet. The code below doesn't throw any exceptions:
$formula = "=COUNT(D:D)"
$excel.cells.item($i, 1).Formula = $formula
UPDATE:
Seems like an issue specific to Excel 2010. In Excel 2016, the same code works fine.
I have tried to mock your approach and came up with the following working code:
foreach($ws in $b.Sheets) {
$ws.Cells.Item(1,1).Formula = "=COUNT($($ws.Name)!D:D)"
}
I've managed to make it work using FormulaLocal instead of Formula. I still believe it's a bug in Excel 2010, since Formula works perfectly fine in Excel 2016. I also still can't insert array formulas containing sheet references in Excel 2010 from script: even assigning FormulaLocal first, and then assigning it's value to FormulaArray doesn't work.

Resources