PHP (WAMP) + shell_exec + powershell + excel macro can not work - excel

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

Related

Why is Excel SaveAs() argument xlLocalSessionChanges not working in Powershell?

I need to use PowerShell to save file.xlsx as file.txt and overwrite the existing file without prompt.
Code:
$xl = new-object -comobject excel.application
$Filename = "file"
$AbsFilePathNoExt=(Get-Item .).FullName+"\"+$Filename
$wb = $xl.Workbooks.Open($AbsFilePathNoExt+".xlsx")
$dft=[Type]::Missing
$wb.SaveAs($AbsFilePathNoExt+".txt",
[Microsoft.Office.Interop.Excel.XlFileFormat]::xlUnicodeText,
$dft,
$dft,
$dft,
$dft,
$dft,
[Microsoft.Office.Interop.Excel.XlSaveConflictResolution]::xlLocalSessionChanges)
$wb.Close()
$xl.Quit()
The 8th argument of SaveAs is xlLocalSessionChanges, which should make Excel overwrite the existing file without prompt. But window still prompts when saving. Why is xlLocalSessionChanges not working?
Excel Workbook.SaveAs Doc
Environment: Windows 10. Excel 365. PowerShell 5.1.

PowerShell opens excel while running script and crashes

I have made some code to run a Macro on 560 Excel files.
There is a small issue with the code, it seems it doesn't save excel file, and opens every excel file, cause excel to crash.
is there a way to have the macro be ran on these 560 files in the backround, and to automatically save once macro is ran, rather than saving it manually?
Thanks
Here is my Code:
# start excel
$excel = New-Object -comobject Excel.Application
# get files
$files = Get-ChildItem 'C:\Users\ME\Desktop\TEST'
# loop through all files in the directory
ForEach ($file in $files){
# open the file
$workbook = $excel.Workbooks.Open($file.FullName)
# make file visible
$excel.Visible = $true
# run macro
$app = $excel.Application
$app.run("PERSONAL.xlsb!Module6.MyMacro")
}
By setting $excel.Visible = $true, the code will become much slower because of all the screen updates involved.
Also, you do not save the workbook after running the code, and because you never quit Excel and remove the COM objects from memory, eventually it will crash because of running out of resources.
Try:
# start excel
$excel = New-Object -comobject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false
# get files and loop through the list
# the usual extension for macro-enabled Excel files is `*.xlsm`.
# if your files have this extension, add -Filter '*.xlsm' to the
# Get-ChildItem command below.
Get-ChildItem -Path 'C:\Users\ME\Desktop\TEST' -File | ForEach-Object {
# open the file
$workbook = $excel.Workbooks.Open($_.FullName)
# run macro
$app = $excel.Application
$app.run("PERSONAL.xlsb!Module6.MyMacro")
$workbook.Close($true) # $true --> save changes
}
$excel.Quit()
# cleanup COM objects
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

Open, save and close Excel

I have an issue opening a spreadsheet via PowerShell, renaming a worksheet, saving and closing Excel. The issue is when run the first time the $WorkBook variable is null. If I run it a second time the script works fine. Also if I add $ExcelDoc.Visible = $true the script works fine. Does anyone have an idea why the script fails on it first run in the form it is below?
$Path = "C:\ScriptRepository\CQC\DataToLoad\"
$FileName = (Get-ChildItem $Path).FullName
$FileName2 = (Get-ChildItem $Path).Name
Start-Sleep 2
$ExcelDoc = New-Object -ComObject Excel.Application
$WorkBook = $ExcelDoc.Workbooks.Open($FileName)
$WorkSheet = $WorkBook.Worksheets.Item(2)
$WorkSheet.Name = "CQCProviders"
$WorkBook.Save()
$WorkBook.Close()
$ExcelDoc.Quit()
While([System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelDoc)) {}

Powershell Excel automatic Bloomberg add-in

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

Powershell Send Key Excel

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.

Resources