I have a very weird problem.
I have some vba scripts called merge1-6 which extracts data from different excel sheets. These 6 resulting text files are merged using another macro "MergeALL" into 1 text file, so everything is on one string.
So far so good, it works fine.
So I wanted to make a powershell script that access the current excel document i have open, and fetch the J29 cell data, and merge this data with the value "0|" to combine a given string.
The actual powershell script I have to pull the cell data is as follows:
Macro : Call BID_MergeXCleanup_TextOut
#This script opens H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.txt and replace empty parts of "domain/users/0|" with "nothing"
#stripping away all entries not needed. Out-File used as output, with -NoNewline to prevent carriage return inserting empty line.
#$workbook = $excel.Workbooks.Open("H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.xlsm") #open workbook
$xl = [Runtime.InteropServices.Marshal]::GetActiveObject(Excel.Application')
$workbook = $xl.workbooks | ?{$_.FullName -eq "H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.xlsm"}
$workbook.sheets.item(1).activate() #opens the sheet and activates it
$WorkbookTotal=$workbook.Worksheets.item(1) #Set sheet data to variable
$value = $WorkbookTotal.Cells.Item(29, 10) # Fetches data in Column 10, Row 29 which is the cell reference J29 where domain is.
$domain = $value.Text #Fetches "domain/users/" from the Fetch-tab of the excel file, to match the correct domain in use and stores result in the $domain variable
$leftoverdomain = '0|' #last part of domain string after the domain/user part
$joinedvariables = -join($domain,$leftoverdomain,"") #Joines the above variables together to form "domain/users/0|" as searchtag to replace as leftover bits.
$b = Get-Content -Path "H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.txt" #Opens text file to replace in.
#Next part uses the $joinedvariables variable of merged search parametres and replaces it with "nothing" and saves the file back.
@(ForEach ($a in $b) {$a.Replace($joinedvariables, '')}) | Out-File "H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.txt" -NoNewline
Start-Sleep -Seconds 0.3
### INFO ###
#I used a reference to the EXCEL cell here, instead of directly from the TXT-file as given what domain has been specified, the info in the TEXT file would vary
#But text in J29 would always equal the domain being used, and thus also correnspond with the one in the text file at all times.
#This way it will automatically always use the correct domain.
So, if I use a standalone reference to the excel document,
$workbook = $excel.Workbooks.Open("H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.xlsm")
...and directly open the workbook, in powershell ISE, the command is successful. BUT does not execute correctly if I call the PS1 script or run it manually from within the excel file. Which is why I started looking for how to access the current excel session leading me to the next method...
If I use
$xl = [Runtime.InteropServices.Marshal]::GetActiveObject('Excel.Application')
to reference the current running application, it successful from both ISE and inside Excel, when I run manually.
In both instances this work, as long as the TXT file that is to be modified exist and has the information in it that is searched for.
So given that I have an "unmodified file" I wanted to launch these macros by calling them from another macro.
This is the VBA code used from within the same excel sheet to launch the macros.
Call BID_1_TextOut
Application.Wait Now + TimeSerial(0, 0, 1)
Call BID_2_TextOut
Application.Wait Now + TimeSerial(0, 0, 1)
Call BID_3_TextOut
Application.Wait Now + TimeSerial(0, 0, 1)
Call BID_4_TextOut
Application.Wait Now + TimeSerial(0, 0, 1)
Call BID_5_TextOut
Application.Wait Now + TimeSerial(0, 0, 1)
Call BID_6_TextOut
Application.Wait Now + TimeSerial(0, 0, 1)
Call BID_MergeALL_TextOut 'Macro MergeALL - Merges all BID-TEXTOUT files to 1 file
Application.Wait Now + TimeSerial(0, 0, 3)
Call BID_MergeXCleanup_TextOut 'Macro MergeXCleanup - This script replace empty parts of "domain/users/0|" with "nothing"
Application.Wait Now + TimeSerial(0, 0, 1)
The two last macros are the important ones. 2nd last macro prepare the file that is to be used in "BID_MergeXCleanup" which is the PS1 script I am calling.
The macros i call are with the following code:
' Script to merge all the BID-TEXT-OUT files into 1 string with UTF32LE encoding.
Sub BID_MergeALL_TextOut()
Set objShell = CreateObject("wscript.Shell")
objShell.Run ("powershell.exe H:\Temp\PublicFolder-powershell\MergeALL_UTF32.ps1")
End Sub
and
'This script opens H:\Temp\PublicFolder-powershell\Create-String-For-Email-Fetch.txt and replace empty parts of "domain/users/0|" with "nothing"
'stripping away all entries not needed.
Sub BID_MergeXCleanup_TextOut()
Set objShell = CreateObject("wscript.Shell")
objShell.Run ("powershell.exe -noexit H:\Temp\PublicFolder-powershell\REPLACE_IN_EmptyDomainUsersPart.ps1")
End Sub
The weird thing is, if I use the "calling script" to run these commands in succession automatically, the last script ALWAYS fails

If I inspect the TXT file afterwards, I see that only the '0|' variable was removed, as it seems it was not able to fetch the J29 information from the Excel document.
If I run each of the macros 1 by 1 from within Excel after each other manually then they execute correctly and the scripts do as I want giving no errors
merge1-6-then-all-then-cleanup
So from what I can tell, my powershell script is able to call the active excel workbook, sheet, cell, get data and all that.
...but I just cant do it with calling the macro from another macro? In this example it fails if I use the "Call BID_MergeXCleanup_TextOut" reference to access the macro.
PS: I also tried to "share" the workbook, in case it was a permission issue, but it still gave error when running the Call-VBA script, but not manually running each macro in succession.
Any idea how I can fix this?
I have a feeling i might not allow the original PS1 file to have a $NULL expression exit, but i am unsure how to add it in.
The first code line that fails is
$workbook.sheets.item(1).activate()
I tried to add $NULL to it in Powershell ISE and then it fails
$null = $workbook.sheets.item(1).activate() <<<--- Fails with *"You cannot call a method on a null-valued expression."*
And i cannot see that i have any undecleared variables in the main script either.
Unsure how to figure this one out.
