RefreshAll() Inconsistent - excel

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

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()

Workbook.SaveAs method is popping Save As dialog box

This was working fine until this weekend, now it's stopped..
I have a powershell script that opens an Excel file as read only, copies a sheet from that file into a new file, then saves the new file to a different location. The script still does all of that, gets to the very end, saves the file to the new location, but now it is opening a "Save as" dialog box, which prevents the script from ever completing. Something change with Powershell? Or the SaveAs method?
# Specify file names/paths
$sourceFile = "C:\source.xlsx"
$exportFile = "C:\export.xlsx"
# Open Excel, hidden/suppress alerts
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $false
$Excel.DisplayAlerts = $false
# Open the source workbook in read-only mode
$sourceWorkbook = $Excel.Workbooks.Open($sourceFile,$null,$true)
# Create a new/blank workbook
$newWorkbook = $Excel.Workbooks.Add()
# Copy sheet from source workbook to new workbook
$sourceWorkbook.Sheets("SheetName").Copy($newWorkbook.Sheets[1])
# Save the new workbook
$newWorkbook.SaveAs($exportFile)

How do I prevent Excel from attempting to connect to its links when opening a file with links in Powershell?

I have a PS script that runs from the Task Scheduler. When a .xlsm file is added to a watched folder it opens this file and gathers specific data from it, then outputs it to a CSV. The problem I've been having recently is with XLSM files that have links to an external SharePoint site. Any time these files are opened with the script it just hangs. If I try to open the file manually Excel first asks me to "Enable Content", then once I click to enable a prompt to input my credentials to connect to the SharePoint site associated with the link.
I can confirm after breaking the link and then running the script that the problem is resolved, so it is definitely this link that is hanging the script up. I've tried looking into methods to break the link before opening the file, but I was not able to gather much. All the resources I could find were in references to updating links via Powershell, not breaking them.
Here are the pieces of my code related to opening the file:
$watchedfolder = "C:\Watched"
$filedirectory = Get-ChildItem $watchedfolder | Where-Object {($_.Extension -eq ".xlsm")} | Select-Object -ExpandProperty Name
foreach ($file in $filedirectory){
$sheetName = "Daily Dash"
#OPEN EXCEL WORKBOOK
$objExcel = New-Object -ComObject Excel.Application
$workbook = $objExcel.Workbooks.Open("C:\Watched\$file")
$sheet = $workbook.Worksheets.Item($sheetName)
$objExcel.Visible = $false
$objExcel.DisplayAlerts = $false
$rowMax = ($sheet.UsedRange.Rows).count
I am unsure of what I can add to this opening portion of my script that will prevent the attempt to connect to the SharePoint site. Any recommendations?
I cannot test this at the moment, but you need to do the settings for the Excel object before opening the file.
Setting the AskToUpdateLinks property to $false should do what you ask for.
#OPEN EXCEL WORKBOOK
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $false
$objExcel.DisplayAlerts = $false
$objExcel.AskToUpdateLinks = $false
$workbook = $objExcel.Workbooks.Open("C:\Watched\$file")
$sheet = $workbook.Worksheets.Item($sheetName)
$rowMax = ($sheet.UsedRange.Rows).count

Dialog box to save file as on existing script

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.

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