I have a problem with automatic run of Excel with Bloomberg add-in included.
When I manually open Excel worksheet, data functions from Bloomberg add-in automatically run.
But when I open same sheet with Powershell and save, there aren't any loaded data
Code - Start Excel and open Workbook:
$xls = New-Object -ComObject Excel.Application
$xls_workbook = $xls.Workbooks.Open("Market_data.xlsx")
$xls_workbook.Activate()
I have tried to force recalculation by these methods:
$xls.Calculate()
$xls.CalculateFull()
$xls.CalculateFullRebuild()
$xls.Workbooks.Application.CalculateFullRebuild()
$xls_workbook.Worksheets(1).Calculate()
But nothing worked. Strange, because, as I have mentioned, manual opening of Excel sheet causes that data from Bloomberg are loaded automatically.
Do you have some experience with this Bloomberg add-in automation? I wanted to check also .xla macros that are included (BloombergUI.xla, BloombergHistory.xla) but they are protected by passwords.
Maybe, is there any option to force running of all Add-ins in Excel?
Or is there any call like $xls.Application.Run() that can run this add-in?
Thank you
Whole code:
$xls = New-Object -ComObject Excel.Application
$xls_workbook = $xls.Workbooks.Open("MarketData.xlsx")
$xls_workbook.Activate()
#calculation
$xls.Calculate()
#$xls_workbook.Aplication.Run("RefreshAllStaticData") - THIS RETURNS ERROR, THAT MACRO IS NOT AVAILABLE OR MACROS ARE DISABLED
#my current option of waiting
$internal_timeout = new-timespan -Seconds $timeout
$sw = [diagnostics.stopwatch]::StartNew()
while ($sw.elapsed -lt $internal_timeout){
}
#maybe next option, how to wait until job finished
#$job = Start-Job -ScriptBlock {
#docalculation
#}
#Wait-Job $job -Timeout $timeout | out-null
$date = Get-Date -Format M_dd_yyyy
$file_to_save = "MarketData_$date.xlsx"
$xls_workbook.SaveAs($file_to_save)
$xls_workbook.Close();
$xls.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xls)
This code worked for me:
$xls = New-Object -ComObject Excel.Application
$xls.Workbooks.Open("C:\blp\API\Office Tools\BloombergUI.xla")
Write-Debug "$file_path$file_name$file_ext"
$xls_workbook = $xls.Workbooks.Open("$file_path$file_name$file_ext")
$xls_workbook.Activate()
$xls_workbook.Application.Run("RefreshAllWorkbooks")
$xls_workbook.Application.Run("RefreshAllStaticData")
$xls.CalculateFull()
Start-Sleep -s $timeout
$date = Get-Date -Format M_dd_yyyy
$file_to_upload = "$file_path$file_name$date$file_ext"
Write-Debug $file_to_upload
$xls_sheet = $xls_workbook.Sheets.Item(1)
$bl_value = $xls_sheet.Cells.Item(2,9).Text
Write-Host $bl_value
$xls_workbook.SaveAs($file_to_upload)
$xls_workbook.Close()
the bloomberg addin is not loaded at all when you use "New-Object -ComObject Excel.Application" to open excel. you can double check by alt+F11 in vba environment
Related
I have the below code that opens a spreadsheet, deletes all connections and "Saves" a new file.
$a = New-Object -COM "Excel.Application"
$a.Visible = $false
$b = $a.Workbooks.Open("F:\Scripts\All Users.xlsx")
do
{
$b.Connections.Item(1).Delete()
$Count = $b.Connections.Count()
} until($Count -eq 0)
$b.SaveAs("F:\Scripts\Users Home Drive Search.xlsx")
$b.Close()
I would like to know two things:
How do I get the sheet to RefreshAll connections? I've tried "$b.Connections.refreshall()" but the refreshall() doesn't exist.
How do I quit Excel application? I ran "New-Object -COM "Excel.Application" | Get-Member -MemberType Methods" and I don't see a quit or exit method.
RefreshAll() is a method of the WorkBook object, so use that to refresh the external connections:
$b.RefreshAll()
To exit Excel and remove the used COM objects from memory, use
$a.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($b)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($a)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
BTW, I would use more descriptive variable names, so $excel instead of $a and $workbook instead of $b to avoid confusion later on.
I have an Excel that is using Power Query to get data from a API. What I would like to do is have this data update every day without having to open the excel myself. So I enabled the setting within excel to Refresh data when opening the file.
So I am trying to create a PowerShell script which open the excel, waits for the query to refresh, and then saves the excel. However I cant get it to wait update the query has refreshed before saving and closing.
code:
$Excel = New-Object -COM "Excel.Application"
$Excel.Visible = $true
$Workbook = $Excel.Workbooks.Open("G:\...\jmp-main-2020-07-17.xlsx")
While (($Workbook.Sheets | ForEach-Object {$_.QueryTables | ForEach-Object {if($_.QueryTable.Refreshing){$true}}}))
{
Start-Sleep -Seconds 1
}
$Excel.Save()
$Excel.Close()
I think your while loop is wrong. You should probably loop over the worksheets in the workbook and for each of them loop over the QueryTables. Then enter a while loop to wait until the Refreshing property turns $false
foreach ($sheet in $Workbook.Sheets) {
$sheet.QueryTables | ForEach-Object {
while ($_.QueryTable.Refreshing) {
Start-Sleep -Seconds 1
}
}
}
As aside: you should clear the COM object you have created after finishing with them to free memory:
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
I am using Windows Task Scheduler to open Excel file and VBA inside that Excel file to close it after data is refreshed.
No PowerShell script needed.
I was able to get #Theo's example working with some small tweaks. Not sure why but the QueryTables property did not have my collection of queries for the sheet however using the ListObjects property did.
$file = "path\to\file.xlsx"
$Excel = New-Object -COM "Excel.Application"
$Excel.Visible = $false
$Workbook = $Excel.Workbooks.Open($file)
foreach ($sheet in ($Workbook.Sheets)) {
$sheet.ListObjects | ForEach-Object{$_.QueryTable.Refresh() | out-null}
$sheet.ListObjects | ForEach-Object{
while ($_.QueryTable.Refreshing) {
Start-Sleep -Seconds 1
}
}
}
And to properly save and exit out of the excel you would use
$Workbook.Save()
$Workbook.Close()
$Excel.Quit()
I'm rather new with PowerShell scripting so please be patient with me :)
I have multiple excel file with OLAP Query connections connecting to Power BI Datasets, following are the script;
$libraryPath = "C:\Repos\AUSD\3.0\Test"
$excel = new-object -comobject Excel.Application
$excel.Visible = $false
# Give delay to open
Start-Sleep -s 3
$allExcelfiles = Get-ChildItem $libraryPath -recurse -include “*.xls*”
foreach ($file in $allExcelfiles)
{
$workbookpath = $file.fullname
Write-Host "Updating " $workbookpath
# Open the Excel file
$excelworkbook = $excel.workbooks.Open($workbookpath)
$connections = $excelworkbook.Connections
# This will Refresh All the pivot tables data.
$excelworkbook.RefreshAll()
# The following script lines will Save the file.
$excelworkbook.Save()
$excelworkbook.Close()
Write-Host "Update Complete " $workbookpath
}
$excel.quit()
It is working fine if following options;
$excel.Visible is true
However this is going to be scheduled in the server and hopefully this could be done in the background, hence the $excel.Visible = $false
This causing the following error;
I suspect this is due to the Automatic sign in which happen when the Excel are open, due to its not being open, its failing the sign in process.
How do I bypass or rather set the credentials/permission right?
I would like to write a script in Powershell which does the following:
Opens Excel Workbook.
Click two times enter on the 2 appearing DialogBoxes.
Runs a macro, saves workbook and quits.
I have a problem with the 2nd step. In my script enter is sent to Powershell window and I see two lines added to the code.
Could anyone help me? Here is my code:
$p1 = "C:\"
$eo = new-object -comobject excel.application;
$eoc = dir $p1 -Include *.xlsm -Recurse
Foreach ($f1 in $eoc)
{
$wb = $eo.workbooks.open($f1.fullname)
while (!$eo.Ready){sleep 0.1}
$eo.Application.SendKeys('~')
while (!$eo.Ready){sleep 0.1}
$eo.Application.SendKeys('~');
$eo.Run("macro_name");
$eo.Application.CalculateFull;
while (!$eo.Ready){sleep 0.1};
$wb.save(); $wb.close()
}
$eo.quit()
You need something like this.
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('window name of your excel file') | Out-Null
This will focus your excel workbook and execute your send key commands.
I call a power shell script from php with shell_exec
Power shell script opens an excel workbook and runs a macro:
$excel = new-object -comobject excel.application
$excelFiles = Get-ChildItem -Path e:\dt\surgicare\something.xlsm
$app = $excel.Application
$workbook = $app.workbooks.open($excelfiles)
$app.Visible = $false
$workbook.Activate()
$app.Run("surgicare_frissites")
$workbook.close($false)
$excel.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($app)
Remove-Variable app
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
Remove-Variable excel
It can run ps script, but it returns error.
I can read in "wamp/logs/php_error.log" that Microsoft Excel cannot open something.xlsm.
The same error is in "wamp/logs/apache_error.log"
If I run power-shell script manually it works fine, there is no error, macro does what it has to do.
Any idea? What did I miss?
Win7x64, PHP 8.0 (XAMPP), Excel 16, in PHP ini add extension=php_com_dotnet.dll
<?php
// starting Excel
$objExcel = new com("excel.application") or die("Unable to instantiate objExcel");
echo "Loaded objExcel, version {$objExcel->Version}\n";
//closing objExcel
$objExcel->Quit();
//free the object
$objExcel = null;
?>
And I see in Firefox: Loaded objExcel, version 16.0