Dialog box to save file as on existing script - excel

I have the following code but I am trying to get it to prompt user with a dynamic dialog box to get the output file to "save as".
$pathtsv = "c:\test.txt"
$pathxlsx = "c:\NBP ESP-152 REV F TEMPLATE.xlsx"
$Excel = New-Object -ComObject "Excel.Application"
$Excel.Visible=$true
$Workbook = $Excel.Workbooks.Open($pathxlsx) # Open Template
$TempWorkbook = $Excel.Workbooks.Opentext($pathtsv) # Open text file in excel
$temp = $excel.Workbooks.Item(2) #select workbook with text
$temp = $temp.Worksheets.Item(1) #select text worksheet
$CopyRange = $temp.Range("A1:G8") #set range
$CopyRange.Copy() #copy data
$workbooksheet = $Workbook.Worksheets.Item(1)#sets doc to copy to
$Workbooksheet.activate()
$PasteRange = $workbooksheet.Range("A3:J10") #sets range
$workbooksheet.Paste($PasteRange)#paste data
#save and close the workbook
$Workbook.Close($true)
$Excel.Quit()
while( [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)){}
[gc]::collect()
[gc]::WaitForPendingFinalizers()
So I tried adding in:
$SaveFileDialog = New-Object windows.forms.savefiledialog
$SaveFileDialog.initialDirectory = [System.IO.Directory]::GetCurrentDirectory()
but it does not seem to be working. Not sure why, maybe because I am still newbish to powershell scripting. I just want to get it to end on the save as dialog box, would be fine. Do I have to cut the end of the original out? (IE. does this get cut out?
$Workbook.Close($true)
$Excel.Quit()
while( [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)){}
[gc]::collect()
[gc]::WaitForPendingFinalizers()
)

You need to do a few things to make this work. First, add a reference to System.Windows.Forms
Add-Type -AssemblyName System.Windows.Forms
After your copy/paste operations create the dialog and set a couple properties
$SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$SaveFileDialog.initialDirectory = [System.IO.Directory]::GetCurrentDirectory()
$SaveFileDialog.Filter = 'All files (*.*)|*.*'
This is where you will need to decide what you want to do when showing the dialog. Do you allow the user to cancel, how do you handle empty paths, incorrect extensions, etc... For the sake of example, I am going to simply continue to show it until a path is chosen. I am not endorsing this as a good choice.
$dialogResult = $null
while($dialogResult -ne "OK"){
$dialogResult = $SaveFileDialog.ShowDialog()
}
You can then access the selected path with the FileName property and perform and checks needed on it
$SaveFileDialog.FileName
Pass this to the excel workbook's SaveAs method. See this answer for details on this method https://stackoverflow.com/a/25289878/3594883
$WorkBook.SaveAs($SaveFileDialog.FileName, 51, [Type]::Missing, [Type]::Missing, $false, $false, 1, 2)
Finally close your workbook and excel. Perform cleanup etc.

Related

Update Excel Data with Password in PowerShell

I need open a excel file with password, update, save and close.
I try this code, but i havent sucessed.
Anyone Can help me?
#Set the file path (can be a network location)
$filePath = "C:\Users\12291\Desktop\Excel\Base Vendas 2020_NOVA.xlsx"
#Create the Excel Object
$excelObj = New-Object -ComObject Excel.Application
#Make Excel visible. Set to $false if you want this done in the background
$excelObj.Visible = $true
$updatelinks = 3D
#Open the workbook
$workBook = $excelObj.Workbooks.Open($filePath, $updatelinks,$false, 0,5 , "vendas")
#Focus on the top row of the "Data" worksheet
#Note: This is only for visibility, it does not affect the data refresh
#$workSheet = $workBook.Sheets.Item("Data")
#$workSheet.Select()
#Refresh all data in this workbook
$workBook.RefreshAll()
#Save any changes done by the refresh
$workBook.Save()
#Uncomment this line if you want Excel to close on its own
#$excelObj.Quit()

Combining Multiple Workbooks Into One Workbook Worksheet With Powershell

I have this Powershell script i'm trying to combine multiple workbooks with single sheets onto one workbook with a single sheet and combine them all on the one sheet. I can't get past the fact it keeps telling me there is no file named $destfile and can't be opened. What is the correct syntax for that?
Thanks
$ExcelObject = New-Object -ComObject excel.application
$ExcelObject.visible=$true
$file1 = 'file1location'
$file2 = 'file2location'
$destfile = 'fileI want to saveas afterits compiled'
$xl = new-object -c excel.application
$xl.displayAlerts = $false # don't prompt the user
$wb1 = $xl.workbooks.open($file1, $null, $true) # open source, readonly
$wb2 = $xl.workbooks.open($file2, $null, $true)
$wb3 = $xl.workbooks.open($destfile) # open target
$sh1_wb2 = $wb2.sheets.item(1) # first sheet in destination workbook
$sheetToCopy = $wb1.sheets.item('Sheet1') # source sheet to copy
$sheetToCopy.copy($sh1_wb2) # copy source sheet to destination workbook
$wb1.close($false) # close source workbook w/o saving
$wb2.close($true) # close and save destination workbook
$xl.quit()
spps -n excel
You can try to use https://github.com/dfinke/ImportExcel
Export data to csv from multiple worksheets with Import-CSV, then combine those CSV files (i suppose that they have identical rows) and import combined CVS back to excel using Export-CSV... quite simple. and does not require any COM manipulations.

How to use PowerShell to write a files content to different rows in Excel

I am trying to automate the following manual task, and am struggling with part of it:
1) Open a text file that contains multiple lines containing data.
2) Copy the contents of this file to the clipboard.
3) Open and Excel spreadsheet.
4) Rename the spreadsheet to Test.
5) Paste the contents of the clipboard.
When this is done manually the content is pasted and each line in the text file is inserted as a new row in column A.
Originally the customer wanted all of the file content to be injected into cell A1. I was able to achieve this with the below PowerShell code.
However they have since changed this back to wanting each line of text to go into a separate row in column A.
I cannot figure out how to do this gracefully via the Get-Content method of copying out the text data. I have seen workarounds to this issue whereby Excel opens the text file and copies the text into an intermediate workbook and then into the final workbook.
Could someone please let me know if it's possible to amend my already working code below so that it adds the text to rows in column A rather than to cell A1?
# Clear the screen of any previous text.
cls
$ExcelFile="C:\Users\User\Desktop\Test\Test.xlsx"
$TextFile="C:\Users\User\Desktop\Test\TestText.txt"
$Content = Get-Content $TextFile -Raw
# Perform operations in Excel based on content of the downloaded file.
$Excel = New-Object -ComObject Excel.Application
# For troubleshooting enable the below to view Excel as file is manipulated:
#$Excel.Visible=$true
# Disable Excel alerts. Hash this line out for troubleshooting.
$Excel.DisplayAlerts = $false
# Set up workbook...
$Workbook = $Excel.Workbooks.Add()
$Data = $Workbook.Worksheets.Item(1)
$Data.Name = 'Test'
# Insert Data
$Data.Cells.Item(1,1) = "$Content"
# Format, save and quit excel
$UsedRange = $Data.UsedRange
$UsedRange.EntireColumn.AutoFit() | Out-Null
$Workbook.SaveAs("$ExcelFile")
$Excel.Quit()
I know that the part I would need to change is as follows, but I'm not sure what to change it to:
# Insert Data
$Data.Cells.Item(1,1) = "$Content"
Many thanks in advance.
To do this, you need to find the last used row in the sheet and write each line from there:
$ExcelFile = "C:\Users\User\Desktop\Test\Test.xlsx"
$TextFile = "C:\Users\User\Desktop\Test\TestText.txt"
# Perform operations in Excel based on content of the downloaded file.
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $false
$Excel.DisplayAlerts = $false
# open the file and select the first worksheet
$WorkBook = $Excel.Workbooks.Open($ExcelFile)
$WorkSheet = $Workbook.Worksheets.Item(1)
# get the first unused row
$row = ($WorkSheet.UsedRange.Rows).Count + 1
# fill in the data
Get-Content -Path $TextFile | ForEach-Object {
$WorkSheet.Cells.Item($row++, 1) = $_
}
# format column A and save the file
$UsedRange = $WorkSheet.UsedRange
$UsedRange.EntireColumn.AutoFit() | Out-Null
$WorkBook.Save()
# quit excel and clean up the used COM objects
$Excel.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WorkSheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WorkBook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
I think the solution would be to read each line in content by for or foreach loop
in loop, write the line's content into the last row of column A in the excel file.
It's will be something like this
foreach($line in $Content){
$Data.Cells.Item($LastRow,1) = $line
}

RefreshAll() Inconsistent

Using PowerShell, I want to open several Excel workbooks, refresh all the links inside and then calculate the sheets so that when other users open them, they see the updated links and do not need to refresh the links. My script works, but not for all the sheets.
I discovered that having the sheet set to manual Calculate prevented it from Calculating on Save and Close, so I added script to change the Calculations to Automatic and then back to Manual, but it didn't work for one of the sheets. The only difference between that sheet and the others is that is it in a different folder, but the script is able to access the folder.
$Excel = new-object -comobject excel.application
$Excel.displayAlerts = $false # don't prompt the user
$Excel.visible = $False;
$wb = $Excel.workbooks.open("C:\Folder1\File1.xlsm")
$xlAutomatic = -4105
$xlCalculationManual = -4135
$Excel.Calculation = $xlAutomatic
$wb.RefreshAll() #refresh links
$wb.close($true) #close and save
$wb = $Excel.workbooks.open("C:\Folder1\File2.xlsm")
$wb.RefreshAll() #refresh links
$wb.Calculate
$wb.close($true) #close and save
$wb = $Excel.workbooks.open("C:\Folder1\File3.xlsm")
$wb.RefreshAll() #refresh links
$wb.Calculate
$wb.close($true) #close and save
$wb = $Excel.workbooks.open("C:\Folder1\Folder2\File4.xlsm") # <-----File that is not updating
$wb.RefreshAll() #refresh links
$wb.Calculate
$wb.close($true) #close and save
$wb = $Excel.workbooks.open("C:\Folder1\File1.xlsm")
$wb.RefreshAll() #refresh links
$wb.Calculate
$Excel.Calculation = $xlCalculationManual
$wb.close($true) #close and save
$Excel.quit()
spps -n excel
I feel like I've got a lot of code that I don't need in here as I try to find what works.
Edit-
This helped me find the initial solution. I just want to understand why it only works for some of the files.
Powershell Script - Open Excel, Update External Data, Save as

How do I export just one worksheet in Excel to a single htm file?

I'm having trouble saving one worksheet from Excel workbook as a single .htm file.
I know if I open up Excel, open my workbook, select the worksheet I want, and do a "Save As" file type .htm it will work. Every time I code it I get "Hitlist.htm" plus a folder named "Hitlist_files" with all the style sheets, etc. Unfortunately, in powershell it does the "save as" with all the other data and supplemental files (extra folders, styling specifications, etc.)
Help. Code below.
#Create and get my Excel Obj
$excel = New-Object -comobject Excel.Application
$excel.visible=$false
$excel.DisplayAlerts=$false
$UserWorkBook = $excel.Workbooks.Open("e:\hitlist\hitlist.xlsx")
#Select first Sheet
$UserWorksheet = $UserWorkBook.Worksheets.Item(1)
#HitList File name and type
$hitlist = "E:\HitList\Hitlist.htm"
$xlHtml = 44
#Save, close, and clean up
#I tried this too...no go - $UserWorkBook.SaveAs($hitlist,$xlHtml)
$UserWorksheet.SaveAs($hitlist,$xlHtml)
$UserWorkBook.close()
$excel.quit()
$excel = $null
I've adjusted your code to your expectations again, after we clarified some more. In particular, look at any line denoted with #changed-grav for my modifications to your existing code, or the very end (#added-grav) for some additional steps I added to fit the exact specs:
(This was tested fully, and appears to be working exactly as you requested - but I did some modifications for my testing, so let me know if I didn't change a value back that you needed)
#Create and get my Excel Obj
$excel = New-Object -comobject Excel.Application
$excel.visible=$false
$excel.DisplayAlerts=$false
$UserWorkBook = $excel.Workbooks.Open("e:\hitlist\hitlist.xlsx")
#Select first Sheet
$UserWorksheet = $UserWorkBook.Worksheets.Item(1)
#HitList File name and type
$hitlistCSV = "e:\hitlist\hitlist.csv" #changed-grav
$hitlistHTML = "e:\hitlist\hitlist.htm" #changed-grav
$xlCSV = 6 #changed-grav
#Save, close, and clean up
$UserWorksheet.SaveAs($hitlistCSV,$xlCSV) #changed-grav
$UserWorkBook.close()
$excel.quit()
$excel = $null
#new functionality, to import the CSV and then export as HTM
#added-grav START
$htmlData = Get-Content $hitlistCSV | ConvertFrom-CSV | ConvertTo-HTML
Set-Content $hitlistHTML $htmlData
Remove-Item $hitlistCSV
#added-grav END

Resources