I am using PowerShell to search a document for a key word (TTF) and then import some data. I am searching a few thousand excel documents and about half way through it started picking up unwanted data.
The code I have is as follows
$condition1 = "TTF"
$fs1 = $ws.cells.find($condition1)
It started getting unwanted data as the excel documents started using "TTF All Day" in another cell which was at the start of the document.
How do I get powershell to only look for "TTF" exactly and not "TTF" followed by more characters.
Thanks
Try using the LookAt:=xlWhole option to specify cells containing only "TTF":
$condition1 = "TTF"
$fs1 = $ws.cells.find($condition1, LookAt:=xlWhole)
This will work
$condition1 = "TTF"
$fs1 = [void]$ws.cells.find($condition1, [Microsoft.Office.Interop.Excel.XlLookAt]::xlWhole)
# This script illustrates how to use the Range.Find method
# with parameters to find exact match
# ------------------------------------------------------------------------------------
# Learn More:
# Range.Find Method: https://learn.microsoft.com/en-us/office/vba/api/Excel.Range.Find
# XlFindLookIn: https://learn.microsoft.com/en-us/office/vba/api/excel.xlfindlookin
# XlLookAt: https://learn.microsoft.com/en-us/office/vba/api/excel.xllookat
# Open Excel
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible=$false
$Excel.DisplayAlerts=$false
# Open Spreadsheet you want to test
$xlSource = "C:\Temp\YourSpreadsheetNameGoesHere.xlsx"
$xlBook = $Excel.Workbooks.Open($xlSource)
$xlSheet = $xlBook.worksheets.item("SheetNameGoesHere")
# What you want to seach
$searchString = "John Smith"
# Column or Range you want to seach
$searchRange = $xlSheet.Range("A1").EntireColumn
# Search
$search = $searchRange.find($searchString,
$searchRange.Cells(1,1),
[Microsoft.Office.Interop.Excel.XlFindLookIn]::xlValues,
[Microsoft.Office.Interop.Excel.XlLookAt]::xlWhole
)
# NOT FOUND
if ($search -eq $null) {
Write-Host "Not found"
}
else { # FOUND
Write-Host "Found at row #" -NoNewline
Write-Host $search.Row
}
# Close Objects
if ($xlBook) { $xlBook.close() }
if ($Excel) { $Excel.quit() }
Related
I'd like to ask you for a help how to save bold text into variable from Excel via Powershell. I'm not a full time developer, just trying to make my life easier with Powershell :)
This is what I have (it's not a lot unfortunately):
# Open file test.xlsx
$excel = Open-ExcelPackage -Path './test.xlsx'
# Copy content of the worsksheet 'Sheet1'
$worksheet = $excel.Workbook.Worksheets['Sheet1']
# Copy specific cell value to the variable
$String = $worksheet.Value
$StringBold =
# Close Excel file
Close-ExcelPackage -ExcelPackage $Excel
I'm able to save content of the file test.xlsx into &worksheet variable. In some cell might be the string 'How are you today Marek?' So the next step should be to save only word Marek into the variable $StringBold
Thanks a lot for any advice.
After some research this seems possible using the ImportExcel Module, you just need to enumerate each cell and then access their .RichText property. Here is an example of how you can achieve it:
$xlsx = Open-ExcelPackage path\to\my.xlsx
$sheet = $xlsx.Workbook.Worksheets['mySheetName']
foreach($cell in $sheet.Cells) {
foreach($richText in $cell.RichText) {
if($richText.Bold) {
[pscustomobject]#{
Address = $cell.Address
Value = $richText.Text
}
}
}
}
Using this Sheet as an example:
The result with this code becomes:
Address Value
------- -----
A2 Marek
A3 Hello
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
I'm working on a PS script to take a row of data from an Excel spreadsheet and populate that data in certain places in a Word document. To elaborate, we have a contract tracking MASTER worksheet that among other things contains data such as name of firm, address, services, contact name. Additionally, we have another TASK worksheet in the same workbook that tracks information such as project owner, project name, contract number, task agree number.
I'm writing a script that does the following:
Ask the user through a message box what kind of contract is being written ("Master", or "Task")
Opens the workbook with the appropriate worksheet opened ("Master" tab or "Task" tab)
Asks the user through a VB InputBox from which Excel row of data they want to use to populate the Word contract
Extracts that row of data from Excel
Outputs certain portions of that row of data to certain location in a Word document
Saves the Word document
Opens the Word document so the user can continue editing it
My question is this - using something like PSExcel, how do I extract that row of data out to variables that can be placed in a Word document. For reference, in case you're going to reply with a snippet of code, here are what the variables are defined as for the Excel portion my script:
$Filepath = "C:\temp\ContractScript\Subconsultant Information Spreadsheet.xlsx"
$Excel = New-Object -ComObject Excel.Application
$Workbook = $Excel.Workbooks.Open($Filepath)
$Worksheet = $Workbook.sheets.item($AgreementType)
$Excel.Visible = $true
#Choosing which row of data
[int]$RowNumber = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the row of data from $AgreementType worksheet you wish to use", "Row")
Additionally, the first row of data in the excel worksheets are the column headings, in case it matters.
I've gotten this far so far:
import-module psexcel
$Consultant = new-object System.Collections.Arraylist
foreach ($data in (Import-XLSX -path $Filepath -Sheet $AgreementType -RowStart $RowNumber))
{
$Consultant.add($data)'
But I'm currently stuck because I can't figure out how to reference the data being added to $consultant.$data. Somehow I need to read in the column headings first so the $data variable can be defined in some way, so when I add the variable $consultant.Address in Word it finds it. Right now I think the variable name is going to end up "$Consultant.1402 S Broadway" which obviously won't work.
Thanks for any help. I'm fairly new to powershell scripting, so anything is much appreciated.
I have the same issue and searching online for solutions in a royal PITA.
I'd love to find a simple way to loop through all of the rows like you're doing.
$myData = Import-XLSX -Path "path to the file"
foreach ($row in $myData.Rows)
{
$row.ColumnName
}
But sadly something logical like that doesn't seem to work. I see examples online that use ForEach-Object and Where-Object which is cumbersome. So any good answers to the OP's question would be helpful for me too.
UPDATE:
Matthew, thanks for coming back and updating the OP with the solution you found. I appreciate it! That will help in the future.
For my current project, I went about this a different way since I ran into lack of good examples for Import-XLSX. It's just quick code to do a local task when needed, so it's not in a production environment. I changed var names, etc. to show an example:
$myDataField1 = New-Object Collections.Generic.List[String]
$myDataField2 = New-Object Collections.Generic.List[String]
# ...
$myDataField10 = New-Object Collections.Generic.List[String]
# PSExcel, the third party library, might want to install it first
Import-Module PSExcel
# Get spreadsheet, workbook, then sheet
try
{
$mySpreadsheet = New-Excel -Path "path to my spreadsheet file"
$myWorkbook = $mySpreadsheet | Get-Workbook
$myWorksheet = $myWorkbook | Get-Worksheet -Name Sheet1
}
catch { #whatever error handling code you want }
# calculate total number of records
$recordCount = $myWorksheet.Dimension.Rows
$itemCount = $recordCount - 1
# specify column positions
$r, $my1stColumn = 1, 1
$r, $my2ndColumn = 1, 2
# ...
$r, $my10thColumn = 1, 10
if ($recordCount -gt 1)
{
# loop through all rows and get data for each cell's value according to column
for ($i = 1; $i -le $recordCount - 1; $i++)
{
$myDataField1.Add($myWorksheet.Cells.Item($r + $i, $my1stColumn).text)
$myDataField2.Add($myWorksheet.Cells.Item($r + $i, $my2ndColumn).text)
# ...
$myDataField10.Add($myWorksheet.Cells.Item($r + $i, $my10thColumn).text)
}
}
#loop through all imported cell values
for ([int]$i = 0; $i -lt $itemCount; $i++)
{
# use the data
$myDataField1[$i]
$myDataField2[$i]
# ...
$myDataField10[$i]
}
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.
$strPath="Path To Spreadsheet.xlsx"
$objExcel=New-Object -ComObject Excel.Application
$objExcel.Visible=$false
$WorkBook=$objExcel.Workbooks.Open($strPath)
$fname = "Facility Name"
$worksheet = $workbook.sheets.item($fname)
$Range = $Worksheet.Range("B1").EntireColumn
$Search = $Range.find("Switch")
I need to be able to find all instances of a string not just one.
I have an excel spreadsheet with IP information and in there, we have Switches ranging from one per workbook all the way up to 10, so what i need to do is be able to find all instances of the word "Switch" and add them to an array i can play with. So all i have to do is find all the values and add them to a simple array. Thanks.
I was playing with it and was able to figure out a pretty simple solution.
$i = 1
$Search = $Range.find("Switch")
while ($i -eq 1) {
if ($Search.value2 -like '*sw*') {
$Search.value2
$Search = $Search.offset(1,0)}
else {$i = 0}
}