Is there a way to store message box settings to be used repetitively in Powershell? - powershell

I'd like to use the same message box repetitively in a Powershell script, without having to reiterate all the settings each time. I initially thought that I would store it as a variable:
$StandardMessage = [System.Windows.Forms.MessageBox]::Show("Repetitive Message.", "Chores.")
But as I found out this simply stores the user's response to the message box in the variable.
What I would like to do is something similar to the following pseudo-code:
$StandardMessage = [System.Windows.Forms.MessageBox]::Show("Repetitive Message.", "Chores.")
While(true){
If(condition){
$StandardMessage
}
If(condition2){
$StandardMessage
}
}
Where the conditions would be time-based. This is essentially displaying a message at specified times during the day.
Asked another way (and perhaps more clearly): Is it possible to 'define' a messagebox without actually 'showing' it?

You need to use a Function my good man!
Function Show-MyMessage{
[System.Windows.Forms.MessageBox]::Show("Repetitive Message.", "Chores.")
}
While(true){
If(condition){
Show-MyMessage
}
If(condition2){
Show-MyMessage
}
}
Edit: Personally I have this function on hand for several of my scripts to use as needed:
Function Show-MsgBox ($Text,$Title="",[Windows.Forms.MessageBoxButtons]$Button = "OK"){
[Windows.Forms.MessageBox]::Show("$Text", "$Title", [Windows.Forms.MessageBoxButtons]::$Button, [Windows.Forms.MessageBoxIcon]::Information) | ?{(!($_ -eq "OK"))}
}
Then I can just call it as needed, like:
Show-MsgBox -Title "You want the truth?" -Text "You can't handle the truth!"
And I've got a pop up with the text and title I want, and an OK button.
Buttons can be specified (there's a pop-up for it in the ISE to give options), and title can be excluded if I am feeling lazy. Only thing I really have to feed it is the message.

Related

Variable being passed in as null - Powershell

So I have an issue that has been bugging me for a few hours now.
I have two functions, Write-Log, and LogProfileRemoval. In Write-Log, I pass in the two arguments as shown here.
LogProfileRemoval('$LogEventDetail', 100000)
But when I check the variables of LogProfileRemoval they are shown like this
$LogEventDetail = '$LogEventDetail' 100000
$LogMethod = $null
I am aware that I have quotes around the variable $LogEventDetail, that was part of my testing to figure this out. Really that variable could be anything and it still concats those two variables into one and leaves the 2nd parameter as a null value.
What am I doing wrong here.
Thanks
function LogProfileRemoval($LogEventDetail, $LogMethod)
{
Switch ($LogMethod)
{
'EventLog' {LogToEventLog($LogEvent)}
}
}
function Write-Log($logDetail, $logEvent=2)
{
$LogEventDetail = New-Object EventLog -Property #{EventTimeStamp=(Get-Date);EventType=$logEvent;EventDetail=$logDetail}
$LogMethod = 1
LogProfileRemoval('$LogEventDetail', 100000)
}
So by not following best practices, was the issue. Weird becuase I have always wrote my powershell scripts like this. Always been a not fan of the Param way of doing it. I changed it to best practice way (sorta) and it worked great.
I would like to know why it didn't work though but overall It just goes to show me to quick being lazy and do it the right way.
Code working shown below
function LogProfileRemoval
{
param(
$LogEventDetail,
$LogMethod
)
Switch ($LogMethod)
{
'EventLog' {LogToEventLog($LogEvent)}
}
}
function Write-Log($logDetail,$logEvent=2)
{
$LogEventDetail = New-Object EventLog -Property #{EventTimeStamp=(Get-Date);EventType=$logEvent;EventDetail=$logDetail}
$LogMethod = 1
LogProfileRemoval -LogEventDetail $LogEventDetail -LogMethod 'EventLog'
}

Prevent user from Enter-pressing on MESSAGE type I?

Is there any way to disable the enter key when a MESSAGE TYPE I is displayed? The users are just pressing away the note without reading it.
We want to force them to actually click the green button to confirm the message instead (Yes, I know it's dumb, but I was tasked to implement this so wcyd).
SELECT SINGLE text
FROM ZWM_MATVERMERK
INTO lv_verm
WHERE matnr = <lf_main>-matnr
AND werk = <lf_main>-werks.
IF lv_verm IS NOT INITIAL.
MESSAGE | Note: { lv_verm } | TYPE 'I'.
CLEAR lv_verm.
ENDIF.
You can use the function module POPUP_TO_CONFIRM to create a modal dialog which gives you more control than the standard MESSAGE TYPE 'I'.
Among others, this function module has the parameter default_button which decides which button is the one highlighted when the popup appears and thus will be considered clicked when the user just presses enter.
DATA lv_answer TYPE c.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
text_question = 'Are you sure?'
default_button = 2
IMPORTING
answer = lv_answer.
" lv_answer will be '1' for yes, '2' for no and 'A' for canceling the dialog.
If you want to make really really sure that the user read the message, then one option is to use POPUP_TO_GET_ONE_VALUE to make the user confirm that they read the message by reciting something from it.
DATA lv_answer TYPE c.
DATA lv_value TYPE pvarfield.
CALL FUNCTION 'POPUP_TO_GET_ONE_VALUE'
EXPORTING
titel = 'Safety check'
textline1 = |This operation will affect { lv_count } items.|
textline2 = |When you are aware of that, please enter "{ lv_count }" below:|
valuelength = 20
IMPORTING
answer = lv_answer
value1 = lv_value.
IF lv_answer = 'J' and lv_value = lv_count.
"...proceed...
ENDIF.
This will look like this:
By the way: There are a lot more standard function modules starting with POPUP_* which cover a wide variety of common use-cases for modal dialogs. Some of those can be really useful.

My google sheets function does the job when run from editor but gives different outcome when trigered by Form submit

I have a google form and a sheet that collects the responses which of course always appear at the bottom. I have been using the following script to copy the last response (which is always on the last row) from the Response sheet (Form Responses 2) to row two of another sheet (All Responses). When run by a trigger on Form Submit the script inserts a blank row into All Responses, then the copied values into another row above the blank row. Please can you help and tell me why and how I might change the script so the blank row is not added:
function CopyLastrowformresponse () {
var ss = SpreadsheetApp.getActive();
var AR = ss.getSheetByName("All Responses");
var FR = ss.getSheetByName("Form responses 2");
var FRlastrow = FR.getLastRow();
AR.insertRowBefore(2);
FR.getRange(FRlastrow, 1, FRlastrow, 22).copyTo(AR.getRange("A2"), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
A few things could be going on here.
You're getting a number of rows equal to FRlastrow, when I think you only want to be getting 1 row.
Apps Script has buggy behavior with onFormSubmit() triggers, so you may to check duplicate triggers (see this answer).
The script isn't fully exploiting the event object provided by onFormSubmit(). Specifically, rather than getting the last row from one sheet, you could use e.values, which is the same data.
I would change the script to be something like this:
function CopyLastrowformresponse (e) {
if (e.values && e.values[1] != "") { // assuming e.values[1] (the first question) is required
SpreadsheetApp.getActive()
.getSheetByName("All Responses")
.insertRowBefore(2)
.getRange(2, 1, 1, e.values.length)
.setValues([e.values]);
}
}
But, ultimately, if all you want to do is simply reverse the order of the results, then I'd ditch Apps Script altogether and just use the =SORT() function.
=SORT('Form responses 2'!A:V, 'Form responses 2'!A:A, FALSE)

How to differentiate as abbreviation for voice response in dialog flow

I have integrated my dialogflow agent with google assistant. There is a welcome intent that will ask you to choose any of the option
Choose any of the sports
1. NBA
2. NHL
3. FIH
It reads the response with ever individual words(as an abbreviation). But when I produce the same in response from webhook, it is not reading the response with individual words(or not considering the response as abbreviation) and reads together. How can I achieve this? Am I missing something in the response?
You likely want to make sure you're sending back SSML in your response, rather than sending back text and letting it convert it to speech, and specifically marking the abbreviations using the <say-as> tag and telling it to interpret the contents as characters.
So you might send it back as something like:
<speak>
Are you interested in learning more about
the <say-as interpret-as="characters">NBA</say-as>,
the <say-as interpret-as="characters">NHL</say-as>
or the <say-as interpret-as="characters">FIH</say-as>?
</speak>
The little pronunciation differences with and without SSML are serious problems. I stick in a speak /speak for everything. Also a unique number I like and a test hook to have speech 'count' or not so there is a way to test things. Also a hook so an intent is triggered for 'repeat that please' :
Point is to use sayUsual for everything ordinary.
// Mostly SSML start char kit as globals
const startSp = "<speak>", endSp = "</speak>";
// Handle "Can you repeat that ?" well
var vfSpokenByMe = "";
// VF near globals what was said, etc
var repeatPossible = {}; repeatPossible.vf = ""; repeatPossible.n = 0;
// An answer from this app to the human in text
function absorbMachineVf( intentNumber, aKind, aStatement )
{
// Numbers reserved for 'repeats'
if( intentNumber > 9000 ) { return; }
// Machine to say this, a number for intents too
repeatPossible.vf = aStatement; repeatPossible.n = intentNumber;
}
// Usual way to say a thing
function sayUsual( n, speechAgent, somethingToSay )
{
// Work with an answer of any sort
absorbMachineVf( n, 'usual', somethingToSay );
// Sometimes we are just pretending, so
if( !testingNow )
{ speechAgent.add( startSp + somethingToSay + endSp ); }
// Make what we said as an answer available 'for sure' to rest of code
vfSpokenByMe = somethingToSay; // Even in simulation
}

How Do I detect Text and Cursor position changes in Word using VSTO

I want to write a word addin that does some computations and updates some ui whenever the user types something or moves the current insertion point. From looking at the MSDN docs, I don't see any obvious way such as an TextTyped event on the document or application objects.
Does anyone know if this is possible without polling the document?
Actually there is a way to run some code when a word has been typed, you can use SmartTags, and override the Recognize method, this method will be called whenever a word is type, which means whenever the user typed some text and hit the space, tab, or enter keys.
one problem with this however is that if you change the text using "Range.Text" it will detect it as a word change and call the function so it can cause infinite loops.
Here is some code I used to achieve this:
public class AutoBrandSmartTag : SmartTag
{
Microsoft.Office.Interop.Word.Document cDoc;
Microsoft.Office.Tools.Word.Action act = new Microsoft.Office.Tools.Word.Action("Test Action");
public AutoBrandSmartTag(AutoBrandEngine.AutoBrandEngine _engine, Microsoft.Office.Interop.Word.Document _doc)
: base("AutoBrandTool.com/SmartTag#AutoBrandSmartTag", "AutoBrand SmartTag")
{
this.cDoc = _doc;
this.Actions = new Microsoft.Office.Tools.Word.Action[] { act };
}
protected override void Recognize(string text, Microsoft.Office.Interop.SmartTag.ISmartTagRecognizerSite site,
Microsoft.Office.Interop.SmartTag.ISmartTagTokenList tokenList)
{
if (tokenList.Count < 1)
return;
int start = 0;
int length = 0;
int index = tokenList.Count > 1 ? tokenList.Count - 1 : 1;
ISmartTagToken token = tokenList.get_Item(index);
start = token.Start;
length = token.Length;
}
}
As you've probably discovered, Word has events, but they're for really coarse actions like a document open or a switch to another document. I'm guessing MS did this intentionally to prevent a crappy macro from slowing down typing.
In short, there's no great way to do what you want. A Word MVP confirms that in this thread.