powershell script calling another script reading excel fails - excel

only new to PowerShell so I hope someone can help me with my little issue.
I've written a script that accepts 2 parameters and opens and reads an excel file (lets call it excelRead.ps1). When I execute this by itself everything works fine.
However, when I call excelRead.ps1 from inside another script the code to open the excel file appears to fail with absolutely no error.
e.g.
. c:\runIt.ps1 -ws "valid - 20140528" -out "$out_file"
Anyone have any ideas as to why this might be happening?

Personally one of the three things I load in my sessions anytime I launch powershell is a script that loads 1 function: Import-Xls (by Francis de la Cerna). (Get it here!) Which really brings me to my point, (which I think was a Hey, Scripting Guy! blog a long time ago): Don't write scripts, write functions.
This would probably be simpler if you wrote your 'other script' as a function that could be called upon, and then run in the context of the current scope. For example, if you had the Import-Xls.ps1 file in the current path you could do something like:
. .\Import-Xls.ps1
$Data = Import-Xls <path to .XLS(x) file> -Worksheet "valid - 20140528"
Then you have the data from that sheet stored in $Data to do with as you please.

Related

How is AppleScriptTask called from Excel 365 VBA on Mac mini running Big Sur?

I am trying to run an AppleScript from VBA in an Excel 365 macro and I keep getting:
Run-time error '5': Invalid procedure call or argument
I have this script called "PythonCommand.scpt" in my /Library/Application Scripts/com.microsoft.Excel folder:
on PythonCommandHandler(pythonScript)
--do shell script "/usr/local/bin/Python3" & pythonScript
return "Handler ended! " & pythonScript
end PythonCommandHandler
I commented out the "do" statement so I should simply get back what I send it. I tested this in the script editor by adding a line to invoke the function and it works just fine.
I have this code in my VBA macro:
Dim result As String
Dim strPyScript As String
strPyScript = "xxxx"
result = AppleScriptTask("/Library/Application Scripts/com.microsoft.Excel/PythonCommand.scpt", "PythonCommandHandler", strPyScript)
and when I run it I get the error '5'.
I tried changing the first argument to just "PythonCommand.scpt" instead of the whole path but got the same error. I tried putting the last argument in as a quoted string instead of using a variable and got the same result. I have looked at this post:
How can I launch an external python process from Excel 365 VBA on OSX?
and started my coding from there (this example had the first argument with no path). Then I read this one:
https://learn.microsoft.com/en-us/office/vba/office-mac/applescripttask from Microsoft which is specific to using the AppleScriptTask command. It lays out the process a bit more clearly but is basically the same. I also looked at this post:
How to simply run an applescript task from mac excel 2016
which has a broken link to a Ron deBruin article which I found here:
https://macexcel.com/examples/setupinfo/applescripttask/index.html
Which is quite clear and easier to read but says basically the same thing. The post with the broken link was resolved by making the script an app and invoking it as a hyperlink. I tried that and it works but there are several shortcomings with that approach: can't pass an argument to the script, can't get anything back from the script, and control does not wait for the script to end before executing the next line of VBA code. I really want to make the AppleScriptTask command work. I feel I must be missing something. If others have gotten this to work I must be doing something wrong. I tried turning on all the references I could find in Tools References but that didn't change anything, I still got the error '5': message. Please help me out here if you can. I really appreciate any help you can offer.
Thanks
Phil
Phil,
The code I use is:
res = AppleScriptTask("selectFile.scpt", "GetFile", args)
NB I don't need to put the full path to the scpt file. I presume this is because it is sandboxed and so vba knows where it is.
BTW I put the scpt file in this folder:
${HOME}/Library/Containers/com.microsoft.Excel/Data/Library/Application Scripts/com.microsoft.Excel
The folder you have specified is not a user folder, but rather a system folder.

How to share a variable between 2 pyRevit scripts?

I am using the latest version of pyRevit, v45.
I'm writing some info in temporary files with
myTempFile = script.get_instance_data_file("id")
This creates a file named pyRevit_2018_xxxx_id.tmp in which I store useful info. If I'm not mistaken, the "xxxx" part is changing every time I reload Revit. Now, I need to get access to this information from another pyRevit script.
How can I retrieve the name of the temp file I need to read? In other words, how do I access "myTempFile" from within the second script, which has no idea of the name of "myTempFile"?
I guess I can share somehow that variable between my script, but what's the proper way to do this? I know this must be a very basic programming question, but I'm indeed not a programmer ;)
Thanks a lot,
Arnaud.
Ok, I realise now that my variables in the 1st script cease to exist after its execution.
So for now I wrote the file name in another file, of which I know the name.. That works.
But if there's a cleaner way to do this, I'd be glad to learn ;)
Arnaud
pyrevit.script module provides 4 different methods for creating temporary files based on their use case:
get_instance_data_file:
for data files marked with Revit instance pid. This means that scripts running on another instance will not see this temp file.
http://pyrevit.readthedocs.io/en/latest/pyrevit/script.html#pyrevit.script.get_instance_data_file
get_universal_data_file:
for temp files accessible to all Revit instances and versions
http://pyrevit.readthedocs.io/en/latest/pyrevit/script.html#pyrevit.script.get_universal_data_file
get_data_file:
Base method to get a standard temp file for current revit version
http://pyrevit.readthedocs.io/en/latest/pyrevit/script.html#pyrevit.script.get_data_file
get_document_data_file:
temp file marked with active document (so scripts working on another document will not see this)
http://pyrevit.readthedocs.io/en/latest/pyrevit/script.html#pyrevit.script.get_document_data_file
Each method uses a pattern to create the temp file name. So as long as the call to the method is the same of different scripts, the method generates the same file name.
Example:
Script 1:
from pyrevit import script
tfile = script.get_data_file('mydata')
Script 2:
from pyrevit import script
tempfile = script.get_data_file('mydata')
In this example tempfile = tfile since the file id is the same.
There is documentation on each so make sure you take a look at those and pick the flavor that serves your purpose.

Linking two Executable to read and write data

First of all let me clear you all what am trying to achieve.
I have an exe which gives me some information when I supply the required data.
I cannot make any changes to the UI of that exe.
Now here are the first parameters that I set:
Electric Parameters
After setting the parameters I give some command through text box and receive the reply in the text area.
Here's how:Input Commands
I will then read each data and write into an excel manually.
Can I automate this whole process?
If so how?
I have thought of Inter Process Communication, but not finding any start.
Also got some guidance on using QTP (a testing tool).
Any help would be very appreciated.
The question is regarding how to automate through QTP, which is a very basic level query. Can't explain each and every concept. However, would try to give some important steps.
Load the required addin...
1) Select all the addins at the start in QTP. Try Tools==> Object spy. Then you would understand which technology the exe is built on. Once this is identified, you need to select only that addin whenever you want to automate that application
2) Launch exe through QTP ==>
SystemUtil.Run (PathOfExe)
3) Read Fields==>
Window("Window").Field("Field").GetROProperty("Value") OR
Window("Window").Field("Field").Set "Command"
4) Read the output ==>
Dim Var
Var == Window("Window").Field("Field").GetROProperty("Value")
5) Write the values in excel ==>
Set objExcel = CreateObject("Excel.Application")
Hope this helps for a start. You should try solutions of different sorts. Let us know if you come across any specific code related issues.

executing script file from azure blob and write its results to file

I'll explain the task requested from me:
I have two containers in Azure, one called "data" and one called "script". In the "data" container there's a txt file with data, and in the "script" container there's a script file.
Now, I need programatically (with WorkerRole) to execute the script file, with the content of the data file as parameters (Example: a script file that accepts a string 's' and returns to the screen "Hello, 's'", when 's' in the string given, and in the data file there's a string), and save the result of the run into another file which needs to be saved in another container called "result".
How do I do all these? I've already uploaded the files and created the blobs programatically, but I can't seem to understand how to execute the file of how to save its result to another file?
Can I please have some help?
Thanks in advance
Here are the steps in pseudo code:
Retrieve the script from the blob(using DownloadToStream())
Compile the script(I will leave this to you as I have no idea what
format your script is)
Load parameters from blob(same as step 1)
Execute script with those parameters.
If your script's can be written as lambda expressions then this becomes a lot easier as you can turn them into Action's
Edit based on your questiions:
DownloadText() is no longer included in Azure Storage 2.0, you only have access to DownloadToStream(). Even if you are using an older version(say 1.7) I would recommend using DownloadToStream() in the event you ever upgrade in the future. This will prevent having to refactor your code.
In terms of executing your script, depending on what type of script it is(if it is c# code you can use this example: Is it possible to dynamically compile and execute C# code fragments?. If you need to execute a different type of script you would need to run it using Process.Start and you can look at this example: http://www.dotnetperls.com/process-start
I do not have much experience with point number 2 but those are the processes I have heard and seen used.

Powershell: commandline applications not working after calling method from module

I have created a powershell module (.psm1) file that includes a few other powershell scripts. We use it for sharepoint.
So basically, here's what happens:
I have a deploy script that retrieves the module location from the registry
It loads the module using the Import-Module cmdlet (using -force switch)
This module in turn loads the Sharepoint 2010 snap in and a few other scripts that I created
It runs runs a deployment script that references functions from the included scripts
It also runs a command line application and sends the output directly to the screen
The script will usually work the first time. However, after a few number of tries the commandline tool will stop working and sending output to the screen altogether. And if I try to run a commandline tool (not a cmd-let) after running my script, it don't worky anymore: no output, nothing is done. Its just the same as hitting enter on a blank prompt. anything powershell specific or running GUI applications will work fine but running any console application will not produce any concievable results. the only solution to this, is to just close my powershell and open it again. it will work for usually once and I will have to close it again. our users certainly wont be happy about that..
The most 'notable' things on the script:
scriptblocks are used extensively (for logging), a script block is sent to a handler that executes it using invokecommand and logs the step
its manipulating sharepoint objects
all objects are properly disposed of
no static variables are created nor changed
There are a few global variables shared across all scripts
What I have tried:
I striped my code to a bare minimum: loading an xml file, and restaring a few windows services but I'm still getting this intermittently. I have no idea which part of the code could cause this. I would love to post the code, but our company policy forbids me to. so my aplogies..
Update as per the comment below:
here's roughly how I use codeblocks. I have this function below that is used everytime I want to make the user aware of a task that I'm executing and what it outcome is.
function DoTask($someString, $scriptBlock, $param)
{
try
{
OutputTaskDescription $someString
InvokeCommand $scriptBlock -ArgumentList $param
OutputResultOK
}
catch
{
OutputResultError $_.tostring()
}
}
it could then be used like this:
$stringVar = "something"
$SpSite = new-spsite
deploySomething 'Deploying something' -param $spsite -ScriptBlock {
dosomethingToObject $stringvar
dosomethingToObject $spSite.Name
}
it would then output something like:
Deploying Something ------------- OK
Deploying Something ------------- ERROR
Also notice that I pass the $spsite in the argument list and I just use the string directly. I still don't understand how this works but it seems like I can access all primitive typed variables even without passing them as arguments but I have to pass more complex objects are params, else they dont have any value.
Update:
after much searching and days of pain. I have found others with the same pain. My code exhibits the same exact symptoms as described here:
http://connect.microsoft.com/PowerShell/feedback/details/496326/stability-problem-any-application-run-fails-with-lastexitcode-1073741502
I guess there is no solution yet to this problem.
After a little while I've noticed that if I've ran some very memory intensive functions, I too have gotten that behavior where everything you try to execute just goes to the prompt again. I'd recommend setting Set-PsDebug -Trace 2 to see what those functions are actually doing. I fixed my issue by doing this and figuring out how to make my functions more efficient.

Resources