<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marcus' Macro Blog &#187; Scripting</title>
	<atom:link href="http://www.mjtnet.com/blog/category/scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mjtnet.com/blog</link>
	<description>Mostly tips, tutorials, articles and news about Macro Scheduler &#38; Windows Automation</description>
	<lastBuildDate>Fri, 03 Feb 2012 16:22:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>How long does xyz take?</title>
		<link>http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/</link>
		<comments>http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 12:14:59 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1787</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/' addthis:title='How long does xyz take?'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Need to measure how long a process or a set of commands in your script takes? We used to have to do this with VBScript&#8217;s Timer function. As of v13 Macro Scheduler has it&#8217;s own Timer function. Timer>result Returns the number of milliseconds that have elapsed since the script was started. So let&#8217;s say we [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/' addthis:title='How long does xyz take?' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


No related posts.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/' addthis:title='How long does xyz take?'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Need to measure how long a process or a set of commands in your script takes?</p>
<p>We used to have to do this with VBScript&#8217;s Timer function.   As of v13 Macro Scheduler has it&#8217;s own Timer function.</p>
<blockquote><p>Timer>result</p>
<p>Returns the number of milliseconds that have elapsed since the script was started.</p></blockquote>
<p>So let&#8217;s say we want to measure how long a script takes to run.  We could use Timer at the top of the script to get the current milliseconds value, then again at the end and take one from the other to get the elapsed duration in milliseconds:</p>
<pre class="brush: macroscript">Timer>startTime
..
.. some code here
..
Timer>endTime
Let>elapsed_seconds={(%endTime%-%startTime%)/1000}
MessageModal>Seconds Elapsed: %elapsed_seconds%</pre>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/' addthis:title='How long does xyz take?' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2012/02/03/how-long-does-xyz-take/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Internet IP Address</title>
		<link>http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/</link>
		<comments>http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 08:55:59 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1612</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/' addthis:title='Get Internet IP Address'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>If you are connected to the Internet here&#8217;s an easy way of getting your public IP address by visiting checkip.dyndns.org: HTTPRequest>http://checkip.dyndns.org/,,GET,,HTMLResponse RegEx>[IPAddress],HTMLResponse,1,ips,num_ips,0 If>num_ips>0 MessageModal>Your IP is %ips_1% Else MessageModal>Error retrieving IP from checkip.dyndns.org Endif No related posts.<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/' addthis:title='Get Internet IP Address' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


No related posts.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/' addthis:title='Get Internet IP Address'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>If you are connected to the Internet here&#8217;s an easy way of getting your public IP address by visiting checkip.dyndns.org:</p>
<pre class="brush: macroscript">HTTPRequest>http://checkip.dyndns.org/,,GET,,HTMLResponse
RegEx>[IPAddress],HTMLResponse,1,ips,num_ips,0
If>num_ips>0
  MessageModal>Your IP is %ips_1%
Else
  MessageModal>Error retrieving IP from checkip.dyndns.org
Endif</pre>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/' addthis:title='Get Internet IP Address' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/06/29/get-internet-ip-address/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calling Macro Scheduler Functions from PowerShell</title>
		<link>http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/</link>
		<comments>http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 11:34:40 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1579</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' addthis:title='Calling Macro Scheduler Functions from PowerShell'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Further to my post about the MacroScript SDK the other day, here&#8217;s an example of loading the MacroScript SDK COM object from PowerShell and running some Macro Scheduler code: $objMS = new-object -comobject "mscript.macroscript" $objMS.Init() $objMS.RunCode( "Run>notepad.exe" + [Environment]::NewLine + "WaitWindowOpen>Untitled - Notepad" + [Environment]::NewLine + "Wait>0.5" + [Environment]::NewLine + "Send>Hello World", "") $objMS.Cleanup() You [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' addthis:title='Calling Macro Scheduler Functions from PowerShell' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/06/09/about-the-macroscript-sdk/' rel='bookmark' title='Permanent Link: About the MacroScript SDK &#8211; How to Run Macro Scheduler Code Within Your Own Applications'>About the MacroScript SDK &#8211; How to Run Macro Scheduler Code Within Your Own Applications</a></li><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li><li><a href='http://www.mjtnet.com/blog/2011/11/14/macro-scheduler-13-is-here/' rel='bookmark' title='Permanent Link: Macro Scheduler 13 Is Here!'>Macro Scheduler 13 Is Here!</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' addthis:title='Calling Macro Scheduler Functions from PowerShell'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Further to my <a href="http://www.mjtnet.com/blog/2011/06/09/about-the-macroscript-sdk/">post about the MacroScript SDK</a> the other day, here&#8217;s an example of loading the MacroScript SDK COM object from PowerShell and running some Macro Scheduler code:</p>
<pre class="brush: powershell">  $objMS = new-object -comobject "mscript.macroscript"
  $objMS.Init()
  $objMS.RunCode( "Run>notepad.exe" + [Environment]::NewLine +
  		"WaitWindowOpen>Untitled - Notepad" + [Environment]::NewLine +
  		"Wait>0.5" + [Environment]::NewLine +
  		"Send>Hello World", "")
  $objMS.Cleanup()</pre>
<p>You will need to put the mscript.dll file into the system path (e.g. System32/SysWow64) or into the PowerShell folder.</p>
<p>Don&#8217;t forget that with the MacroScript SDK you can retrieve information and query the data back to PowerShell using the GetVar function (<a href="http://www.mjtnet.com/blog/2011/06/09/about-the-macroscript-sdk/">see previous post</a>).  So for all you system administrators using PowerShell but needing the GUI automation capabilities of Macro Scheduler as well, the <a href="http://www.mjtnet.com/macroscript_sdk.htm">MacroScript SDK</a> is the perfect companion.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' addthis:title='Calling Macro Scheduler Functions from PowerShell' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/06/09/about-the-macroscript-sdk/' rel='bookmark' title='Permanent Link: About the MacroScript SDK &#8211; How to Run Macro Scheduler Code Within Your Own Applications'>About the MacroScript SDK &#8211; How to Run Macro Scheduler Code Within Your Own Applications</a></li><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li><li><a href='http://www.mjtnet.com/blog/2011/11/14/macro-scheduler-13-is-here/' rel='bookmark' title='Permanent Link: Macro Scheduler 13 Is Here!'>Macro Scheduler 13 Is Here!</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Customizing Message/Input Boxes</title>
		<link>http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/</link>
		<comments>http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 12:13:00 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1563</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/' addthis:title='Customizing Message/Input Boxes'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Every now and then someone asks something like &#8220;How do I change the font in a modal dialog box?&#8221; or &#8220;Can I make an Input box multi-line?&#8221;. Well, no, you can&#8217;t do those things to the standard Message/MessageModal or Input box functions. But, don&#8217;t forget that with Macro Scheduler you have the ability to create [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/' addthis:title='Customizing Message/Input Boxes' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/' rel='bookmark' title='Permanent Link: Undocumented Internal Dialog Event Parameters'>Undocumented Internal Dialog Event Parameters</a></li><li><a href='http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/' rel='bookmark' title='Permanent Link: New Video: Using The Debugger'>New Video: Using The Debugger</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/' addthis:title='Customizing Message/Input Boxes'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Every now and then someone asks something like &#8220;How do I change the font in a modal dialog box?&#8221; or &#8220;Can I make an Input box multi-line?&#8221;.</p>
<p>Well, no, you can&#8217;t do those things to the standard Message/MessageModal or Input box functions.  But, don&#8217;t forget that with Macro Scheduler you have the ability to create your own dialogs and make them act and feel pretty much any way you like.  So the answer to the above questions, is &#8220;Create your own versions&#8221;.</p>
<p>As an example, let&#8217;s say you want a modal dialog that looks and acts much like the standard modal message box created by MessageModal.  Only you want the text to be green in an italicized aerial font.  Here you go:</p>
<pre class="brush: macroscript">//this would go at the top - customize as you wish
Dialog>CustomMsgBox
object CustomMsgBox: TForm
  Left = 493
  Top = 208
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  BorderStyle = bsSingle
  Caption = 'My Message'
  ClientHeight = 170
  ClientWidth = 319
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object MSMemo1: tMSMemo
    Left = 0
    Top = 0
    Width = 321
    Height = 137
    Font.Charset = ANSI_CHARSET
    Font.Color = clGreen
    Font.Height = -11
    Font.Name = 'Arial'
    Font.Style = [fsBold, fsItalic]
    ParentFont = False
    TabOrder = 0
  end
  object MSButton1: tMSButton
    Left = 121
    Top = 143
    Width = 75
    Height = 25
    Caption = 'OK'
    DoubleBuffered = True
    ModalResult = 2
    ParentDoubleBuffered = False
    TabOrder = 1
    DoBrowse = False
    BrowseStyle = fbOpen
  end
end
EndDialog>CustomMsgBox

SRT>ShowMsg
  SetDialogProperty>CustomMsgBox,,Position,poScreenCenter
  SetDialogProperty>CustomMsgBox,MSMemo1,Text,ShowMsg_Var_1
  Show>CustomMsgBox,r
END>ShowMsg

//do this to call your message
Let>MyMsg=Hello world, this is a lovely custom message box
GoSub>ShowMsg,MyMsg</pre>
<p>And don&#8217;t forget that once created you can call the dialog any time you like.  And if you want to use it in lots of scripts then put the dialog block and subroutine into an include file and use Include> at the top of each script you want to use it in.</p>
<p>Now, it&#8217;s over to you.  Use your imagination and style the dialog any way you like.  We have some Custom Dialog tutorials here: <a href="http://www.mjtnet.com/blog/2010/12/16/video-tutorial-an-introduction-to-custom-dialogs/">Part1</a>, <a href="http://www.mjtnet.com/blog/2011/01/10/video-tutorial-custom-dialogs-part-2/">Part2</a></p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/' addthis:title='Customizing Message/Input Boxes' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/' rel='bookmark' title='Permanent Link: Undocumented Internal Dialog Event Parameters'>Undocumented Internal Dialog Event Parameters</a></li><li><a href='http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/' rel='bookmark' title='Permanent Link: New Video: Using The Debugger'>New Video: Using The Debugger</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scraping Data From Web Pages</title>
		<link>http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/</link>
		<comments>http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/#comments</comments>
		<pubDate>Fri, 20 May 2011 13:02:58 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1547</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/' addthis:title='Scraping Data From Web Pages'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>I&#8217;ve seen quite a lot of requests lately from people wanting to know how to extract text from web pages. Macro Scheduler&#8217;s optional WebRecorder add-on simplifies the automation of web pages and includes functions for extracting tables, text or HTML from web page elements. WebRecorder&#8217;s Tag Extraction wizard makes it easy to create the code. [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/' addthis:title='Scraping Data From Web Pages' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/' addthis:title='Scraping Data From Web Pages'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>I&#8217;ve seen quite a lot of requests lately from people wanting to know how to extract text from web pages.</p>
<p>Macro Scheduler&#8217;s optional <a href="http://www.mjtnet.com/webrecorder.htm">WebRecorder</a> add-on simplifies the automation of web pages and includes functions for extracting tables, text or HTML from web page elements.  WebRecorder&#8217;s Tag Extraction wizard makes it easy to create the code.</p>
<p>Sometimes you can choose a specific HTML element and identify it uniquely via it&#8217;s ID or NAME attribute.  But other times you might want all the text from the whole page, or you may need to extract the entire page and then parse out the bits you&#8217;re interested in using RegEx or some other string manipulation functions.  </p>
<p>To extract an entire page I specify the BODY element.  If you want to extract data from web pages it does help if you know a little about HTML.  And if you do you&#8217;ll know that each page has just one BODY element which contains the code making up the visible portion of the page. </p>
<p>Here&#8217;s code produced using WebRecorder when navigating to mjtnet.com and using the Tag Extraction wizard to extract the BODY text:</p>
<pre name="code" class="macroscript">IE_Create>0,IE[0]

IE_Navigate>%IE[0]%,http://www.mjtnet.com/,r
IE_Wait>%IE[0]%,r
Wait>delay

//Modify buffer size if required (you may get a crash if buffer size too small for data) ...
Let>BODY0_SIZE=9999
IE_ExtractTag>%IE[0]%,,BODY,0,0,BODY0,r
MidStr>r_6,1,r,BODY0

MessageModal>BODY0</pre>
<p>The macro simply displays just the text in a message box but could be set to pull out the full HTML.  You could then parse it with RegEx to get the information you are interested in.  </p>
<p>You will need WebRecorder installed for the above to work.</p>
<p>If you don&#8217;t have WebRecorder you can do the same with a bit more work using VBScript.  Some library functions for doing this can be found <a href="http://www.mjtnet.com/usergroup/viewtopic.php?t=1461">here</a> and <a href="http://www.mjtnet.com/usergroup/viewtopic.php?t=4660">here</a>.</p>
<p>So here&#8217;s the equivalent in VBScript:</p>
<pre name="code" class="macroscript">VBSTART
Dim IE

'Creates IE instance
Sub CreateIE
  Set IE = CreateObject("InternetExplorer.Application")
  IE.Visible=1
End Sub

'Navigate to an IE instance
Sub Navigate(URL)
  IE.Navigate URL
  do while IE.Busy
  loop
End Sub

'This function extracts text from a specific tag by name and index
'e.g. TABLE,0 (1st Table element) or P,1 (2nd Paragraph element)
'set all to 1 to extract all HTML, 0 for only inside text without HTML
Function ExtractTag(TagName,Num,all)
  dim t
  set t = IE.document.getElementsbyTagname(Tagname)
  if all=1 then
    ExtractTag = t.Item(Num).outerHTML
  else
    ExtractTag = t.Item(Num).innerText
  end if
End Function
VBEND

VBRun>CreateIE
VBRun>Navigate,www.mjtnet.com

VBEval>ExtractTag("BODY",0,0),BodyText
MessageModal>BodyText</pre>
<p>But what if you already have a macro which already opens IE, or works against an already open instance of IE?  The above macros need to create the IE instance before they can access them and extract data from them.  You may have a macro that already starts IE some other way &#8211; maybe just by using a RunProgram or ExecuteFile call, or indirectly via some other application.   Many times people tackle the extraction of data from such an IE window by sending keystrokes to do a Select-All, Edit/Copy and then use GetClipboard; or even File/Save As to save the HTML to a file.  This of course adds time and can be unreliable.   So how else can we do it?</p>
<p>Well, <a href="http://www.mjtnet.com/usergroup/viewtopic.php?t=4660">this tip</a> shows us a function we can use to attach to an existing IE instance.  So let&#8217;s use that and then use our ExtractTag function to pull out the BODY HTML:</p>
<pre name="code" class="macroscript">VBSTART
Dim IE

' Attaches to an already running IE instance with given URL
Sub GetIE(URL)
  Dim objInstances, objIE
  Set objInstances = CreateObject("Shell.Application").windows
  If objInstances.Count > 0 Then '/// make sure we have instances open.
    For Each objIE In objInstances
      If InStr(objIE.LocationURL,URL) > 0 then
        Set IE = objIE
      End if
    Next
  End if
End Sub

'This function extracts text from a specific tag by name and index
'e.g. TABLE,0 (1st Table element) or P,1 (2nd Paragraph element)
'set all to 1 to extract all HTML, 0 for only inside text without HTML
Function ExtractTag(TagName,Num,all)
  dim t
  set t = IE.document.getElementsbyTagname(Tagname)
  if all=1 then
    ExtractTag = t.Item(Num).outerHTML
  else
    ExtractTag = t.Item(Num).innerText
  end if
End Function
VBEND

VBRun>GetIE,www.mjtnet.com

VBEval>ExtractTag("BODY",0,1),BodyHTML
MessageModal>BodyHTML</pre>
<p>This snippet assumes a copy of IE is already open and pointing to www.mjtnet.com.  The GetIE call creates a link to that IE window and then we use the ExtractTag function to pull out the HTML of the BODY element.</p>
<p>These examples use the BODY element, which will contain everything displayed on the page.  As I mentioned before you can be more specific and specify some other element, and with WebRecorder, or a modified version of the ExtractTag VBScript function use other attributes to identify the element (the existing VBScript ExtractTag function shown above just uses the numeric index).  WebRecorder tries to make it simple by giving you a point and click wizard, making some assumptions for you, so that you need not fully understand the HTML of the page.  But it still helps you understand HTML.  Looking at the source of the page you should be able to identify the element you need to extract from.  And whether you extract directly from that or extract the BODY and then use RegEx being prepared to delve into the HTML source is going to get you further.</p>
<p><strong>UPDATE: 19th January 2012</strong></p>
<p>As of version 13.0.06 Macro Scheduler now includes a function called IEGetTags.  For a given tag type and IE tab this will retrieve an array of tag contents.  It can extract just the text, or html of the tags.  This example extracts the inner HTML of all DIV elements in the open IE document currently at www.mjtnet.com:</p>
<pre name="code" class="macroscript">IEGetTags>mjtnet.com,DIV,H,divArr</pre>
<p>You can then cycle through each one with a Repeat Until</p>
<pre name="code" class="macroscript">If>divArr_count>0
  Let>k=0
  Repeat>k
    Let>k=k+1
    Let>this_div_html=divArr_%k%
    ..
    .. do something with it
    .. e.g. use RegEx or substring searching to determine
    .. if this is the DIV you want and extract from it
    ..
  Until>k=divArr_count
Endif</pre>
<p>To further identify the tag you are interested in, or find the data you want, you can use RegEx, <a href="http://www.mjtnet.com/blog/2009/02/26/sneak-peak-simplified-regular-expression-support/">EasyPatterns</a>, or string functions.</p>
<p>Macro Scheduler 13.0.06 and above also has a function called IETagEvent which will let you simulate a Click on a given tag, focus it, or modify its value.  So once you have identified a tag using IEGetTags and your Repeat/Until loop you can click on it, focus it or modify its value (e.g. for form fields).</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/' addthis:title='Scraping Data From Web Pages' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Video: Using The Debugger</title>
		<link>http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/</link>
		<comments>http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 09:44:31 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1495</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/' addthis:title='New Video: Using The Debugger'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Macro Scheduler veteran John Brozycki has put together this fantastic video tutorial all about Macro Scheduler&#8217;s debugging capabilities. The video is 18 minutes long and demonstrates every debug feature, showing examples of their use and talks about how useful the debugger can be for problem resolution as well as script creation. Take a look: A [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/' addthis:title='New Video: Using The Debugger' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/11/09/video-preview-6/' rel='bookmark' title='Permanent Link: Video Preview #6'>Video Preview #6</a></li><li><a href='http://www.mjtnet.com/blog/2011/09/02/mjtnet-youtube-channel/' rel='bookmark' title='Permanent Link: MJTNet YouTube Channel'>MJTNet YouTube Channel</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/' addthis:title='New Video: Using The Debugger'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p><a href="http://www.mjtnet.com/macro_scheduler.htm">Macro Scheduler</a> veteran John Brozycki has put together this fantastic video tutorial all about Macro Scheduler&#8217;s debugging capabilities.  The video is 18 minutes long and demonstrates every debug feature, showing examples of their use and talks about how useful the debugger can be for problem resolution as well as script creation.  Take a look:</p>
<div id="kadoo_video_container_14137368-197"><object height="290" width="504" id="video_detector_14137368-197"><param value="http://divshare.com/flash/video_flash_detector.php?data=YTo2OntzOjU6ImFwaUlkIjtzOjE6IjQiO3M6NjoiZmlsZUlkIjtpOjE0MTM3MzY4O3M6NDoiY29kZSI7czoxMjoiMTQxMzczNjgtMTk3IjtzOjY6InVzZXJJZCI7aToyMTUxMjk0O3M6NDoidGltZSI7aToxMjk4NDQ5NDIxO3M6MTI6ImV4dGVybmFsQ2FsbCI7aToxO30=&amp;autoplay=default&amp;id=14137368-197" name="movie"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="wmode" value="opaque"></param><embed wmode="opaque" height="290" width="504" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" src="http://divshare.com/flash/video_flash_detector.php?data=YTo2OntzOjU6ImFwaUlkIjtzOjE6IjQiO3M6NjoiZmlsZUlkIjtpOjE0MTM3MzY4O3M6NDoiY29kZSI7czoxMjoiMTQxMzczNjgtMTk3IjtzOjY6InVzZXJJZCI7aToyMTUxMjk0O3M6NDoidGltZSI7aToxMjk4NDQ5NDIxO3M6MTI6ImV4dGVybmFsQ2FsbCI7aToxO30=&amp;autoplay=default&amp;autoplay=default&amp;id=14137368-197"></embed></object></div>
<p>A larger version of the video can be found <a href="http://www.mjtnet.com/demos/using_macro_schedulers_debugger.html">here</a>.</p>
<p>John Brozycki is an information security professional who uses Macro Scheduler as a tool to accomplish a wide range of tasks in his daily activities. His personal web site is <a href="http://www.trueinsecurity.com" target="_new">www.trueinsecurity.com</a>.</p>
<p>I think this is an excellent tutorial which all script developers should benefit from.  Thanks John!</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/' addthis:title='New Video: Using The Debugger' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/11/09/video-preview-6/' rel='bookmark' title='Permanent Link: Video Preview #6'>Video Preview #6</a></li><li><a href='http://www.mjtnet.com/blog/2011/09/02/mjtnet-youtube-channel/' rel='bookmark' title='Permanent Link: MJTNet YouTube Channel'>MJTNet YouTube Channel</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/02/23/new-video-using-the-debugger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Undocumented Internal Dialog Event Parameters</title>
		<link>http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/</link>
		<comments>http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/#comments</comments>
		<pubDate>Tue, 08 Feb 2011 15:35:13 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1460</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/' addthis:title='Undocumented Internal Dialog Event Parameters'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>In this forum post Armsys asks how he can determine which key the user pressed in an OnKeyPress dialog event handler. The solution I posted reveals an undocumented feature: Internal event parameters. While there is a sample macro called &#8220;Dialogs &#8211; MouseOver&#8221; which ships with Macro Scheduler and demonstrates these event parameters, they are missing [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/' addthis:title='Undocumented Internal Dialog Event Parameters' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/05/23/why-cant-i-colour-my-dialog-buttons/' rel='bookmark' title='Permanent Link: Why Can&#8217;t I Colour My Dialog Buttons?'>Why Can&#8217;t I Colour My Dialog Buttons?</a></li><li><a href='http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/' rel='bookmark' title='Permanent Link: Customizing Message/Input Boxes'>Customizing Message/Input Boxes</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/' addthis:title='Undocumented Internal Dialog Event Parameters'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>In <a href="http://www.mjtnet.com/usergroup/viewtopic.php?t=6740">this forum post</a> Armsys asks how he can determine which key the user pressed in an OnKeyPress dialog event handler.  The solution I posted reveals an undocumented feature:  Internal event parameters.  </p>
<p>While there is a sample macro called &#8220;Dialogs &#8211; MouseOver&#8221; which ships with Macro Scheduler and demonstrates these event parameters, they are missing from the help file.</p>
<p>So here&#8217;s a short 3 minute video showing how this sample script works and demonstrating how you can determine what event parameters are available for use.</p>
<div id="kadoo_video_container_14002087-553"><object height="290" width="504" id="video_detector_14002087-553"><param value="http://divshare.com/flash/video_flash_detector.php?data=YTo2OntzOjU6ImFwaUlkIjtzOjE6IjQiO3M6NjoiZmlsZUlkIjtpOjE0MDAyMDg3O3M6NDoiY29kZSI7czoxMjoiMTQwMDIwODctNTUzIjtzOjY6InVzZXJJZCI7aToyMTUxMjk0O3M6NDoidGltZSI7aToxMjk3MTc5Mzc4O3M6MTI6ImV4dGVybmFsQ2FsbCI7aToxO30=&amp;autoplay=default&amp;id=14002087-553" name="movie"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="wmode" value="opaque"></param><embed wmode="opaque" height="290" width="504" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" src="http://divshare.com/flash/video_flash_detector.php?data=YTo2OntzOjU6ImFwaUlkIjtzOjE6IjQiO3M6NjoiZmlsZUlkIjtpOjE0MDAyMDg3O3M6NDoiY29kZSI7czoxMjoiMTQwMDIwODctNTUzIjtzOjY6InVzZXJJZCI7aToyMTUxMjk0O3M6NDoidGltZSI7aToxMjk3MTc5Mzc4O3M6MTI6ImV4dGVybmFsQ2FsbCI7aToxO30=&amp;autoplay=default&amp;autoplay=default&amp;id=14002087-553"></embed></object></div>
<p>(Don&#8217;t forget you can view full screen and/or change the quality with the options in the video control panel above).</p>
<p>If you&#8217;re completely new to custom dialogs you might also want to watch <a href="http://www.mjtnet.com/demos/dialogs1.html">part 1</a> and <a href="http://www.mjtnet.com/demos/dialogs2.html">part 2</a> of the custom dialog video tutorials first.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/' addthis:title='Undocumented Internal Dialog Event Parameters' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/05/23/why-cant-i-colour-my-dialog-buttons/' rel='bookmark' title='Permanent Link: Why Can&#8217;t I Colour My Dialog Buttons?'>Why Can&#8217;t I Colour My Dialog Buttons?</a></li><li><a href='http://www.mjtnet.com/blog/2011/06/08/customizing-messageinput-boxes/' rel='bookmark' title='Permanent Link: Customizing Message/Input Boxes'>Customizing Message/Input Boxes</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/02/08/undocumented-internal-dialog-event-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slow Mouse Move</title>
		<link>http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/</link>
		<comments>http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 13:33:06 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1438</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/' addthis:title='Slow Mouse Move'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>A support request came in today asking how to show the mouse moving from one point to another slowly enough to be visible in a video demo. The regular MouseMove function simply &#8220;jumps&#8221; the mouse cursor straight to the given point, without passing any points between wherever it was to start with and that end [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/' addthis:title='Slow Mouse Move' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


No related posts.]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/' addthis:title='Slow Mouse Move'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>A support request came in today asking how to show the mouse moving from one point to another slowly enough to be visible in a video demo.  </p>
<p>The regular MouseMove function simply &#8220;jumps&#8221; the mouse cursor straight to the given point, without passing any points between wherever it was to start with and that end point.  So the question was how to specify a start point and an end point and show the mouse moving on a line between them.</p>
<p>To achieve this we need to determine what that line is.  We don&#8217;t want to move to *every* point between those two points on both the x and y axis.  So how do we do it?</p>
<p>Well, it was a long time ago but deep in the recesses of my mind was a little equation we learnt in mathematics at school.  I admit I had to look it up.  It was the &#8220;slope-intercept&#8221; equation:</p>
<blockquote><p>y = mx + b</p></blockquote>
<p>The slope &#8220;m&#8221; is the change in y over the change in x:</p>
<blockquote><p>m = (y2 &#8211; y1) / (x2 &#8211; x1)</p></blockquote>
<p>Once we have that we can calculate b (the y-intercept) given a known point (e.g. the start point) and then for each x we can calculate y.  </p>
<p>So here&#8217;s a script which will move the mouse slowly through the line between two given points:</p>
<pre name="code" class="macroscript">Let>startX=20
Let>startY=100
Let>endX=300
Let>endY=400
Let>delay_interval=0.001

//remember school math?
//equation of a line is y = mx+b

//m = y2-y1 / x2-x1
Let>m={(%endY%-%startY%)/(%endX%-%startX%)}
//b = y-mx
Let>b={%startY%-(%m% * %startX%)}

Let>x=startX
Let>y=startY
Repeat>x
   //y = mx+b
   Let>y={Trunc((%m% * %x%) + %b%)}
   MouseMove>x,y
   Wait>delay_interval
   If>endX>startX
     Let>x=x+1
   Else
     Let>x=x-1
   Endif
Until>x=endX</pre>
<p>This probably isn&#8217;t much use to most people, but it&#8217;s a little bit of fun.  Maybe you can jazz up your scripts to animate the movement of the cursor or something <img src='http://www.mjtnet.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   </p>
<p>Doing anything a little bit out of the ordinary with Macro Scheduler?  Let me know.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/' addthis:title='Slow Mouse Move' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2011/01/18/slow-mouse-move/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mixing the Native Excel Functions with VBScript</title>
		<link>http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/</link>
		<comments>http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 11:14:33 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1407</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/' addthis:title='Mixing the Native Excel Functions with VBScript'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Macro Scheduler comes complete with some native functions for controlling Excel, such as XLOpen, XLGetCell, XLSetCell and others. Obviously, although we intend to add more functions over time, not every possible Excel function has been duplicated. So sometimes you may want to utilise COM via VBScript which allows you to access the entire Excel API. [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/' addthis:title='Mixing the Native Excel Functions with VBScript' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li><li><a href='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' rel='bookmark' title='Permanent Link: Calling Macro Scheduler Functions from PowerShell'>Calling Macro Scheduler Functions from PowerShell</a></li><li><a href='http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/' rel='bookmark' title='Permanent Link: Scraping Data From Web Pages'>Scraping Data From Web Pages</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/' addthis:title='Mixing the Native Excel Functions with VBScript'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p><a href="http://www.mjtnet.com/macro_scheduler.htm">Macro Scheduler</a> comes complete with some native functions for controlling Excel, such as <a href="http://www.mjtnet.com/OnlineHelp/xlopen.htm">XLOpen</a>, <a href="http://www.mjtnet.com/OnlineHelp/xlgetcell.htm">XLGetCell</a>, <a href="http://www.mjtnet.com/OnlineHelp/xlsetcell.htm">XLSetCell</a> and <a href="http://www.mjtnet.com/OnlineHelp/msched12_ftsearch.html?zoom_query=Excel">others</a>.  Obviously, although we intend to add more functions over time, not every possible Excel function has been duplicated.  So sometimes you may want to utilise COM via VBScript which allows you to access the entire Excel API.  There are <a href='http://www.mjtnet.com/search.htm?q="excel.application"'>plenty of examples</a> of this here in the blog and on the forums.</p>
<p>But what if you want to use a combination of both?  You might already have a script which uses the native XL functions to open a sheet and get or set some data.  Let&#8217;s say you now want to augment this with an Excel method which is not exposed by the native functions.  Rather than re-writing your entire script to use VBScript, is there a way we can let VBScript take over?</p>
<p>While it&#8217;s not possible to share native XL references with VBScript object references, what we can do is have VBScript attach to an open instance of Excel using the <a href="http://support.microsoft.com/kb/288902">GetObject</a> function.  So sometime after running XLOpen we could then run a VBScript function which does a GetObject to get an object reference to Excel and then after that we are able to utlise any Excel function we like via VBScript.  </p>
<p>The following script demonstrates:</p>
<pre name="code" class="macroscript">VBSTART
  Dim xlApp
  Dim xlBook
  Sub GetXL
    Set xlApp = GetObject(,"Excel.Application")
    Set xlBook = xlApp.ActiveWorkbook
  End Sub

  Function FindCell(Sheet,Data)
    Dim theCell
    Dim xlValues
    xlValues = -4163

    Dim xlSheet
    Set xlSheet = xlBook.Worksheets(Sheet)
    xlSheet.Range("A1").Select
    Set theCell = xlSheet.Cells.Find(Data, xlApp.ActiveCell, xlValues)
    FindCell = CStr(theCell.Row) &#038; ":" &#038; CStr(theCell.Column)
  End Function
VBEND

//Open an XLS file natively
XLOpen>%SCRIPT_DIR%\example.xls,1,xlH

//Call GetXL to give VBScript a reference to the XL instance
VBRun>GetXL

//now we can access any XL function via VBScript
VBEval>FindCell("Sheet1","Price"),res</pre>
<p>The only thing to be careful of is that there are no existing copies of Excel open before the one opened by XLOpen because according to the <a href="http://support.microsoft.com/kb/288902">Microsoft docs</a> GetObject will attach to the first opened instance.  You could of course make the script check for this.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/' addthis:title='Mixing the Native Excel Functions with VBScript' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li><li><a href='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' rel='bookmark' title='Permanent Link: Calling Macro Scheduler Functions from PowerShell'>Calling Macro Scheduler Functions from PowerShell</a></li><li><a href='http://www.mjtnet.com/blog/2011/05/20/scraping-data-from-web-pages/' rel='bookmark' title='Permanent Link: Scraping Data From Web Pages'>Scraping Data From Web Pages</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2010/12/15/mixing-the-native-excel-functions-with-vbscript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Native Function Aliases for Win32 Functions</title>
		<link>http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/</link>
		<comments>http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 11:08:16 +0000</pubDate>
		<dc:creator>Marcus Tettmar</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.mjtnet.com/blog/?p=1350</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/' addthis:title='Creating Native Function Aliases for Win32 Functions'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>The other day I posted a response on the forums which uses LibFunc to run the Win32 API function GetKeyState. This prompted someone to email me the following: I didn&#8217;t know the Win API call to check for a key being down. The API call works but have you considered adding a native MS command [...]<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/' addthis:title='Creating Native Function Aliases for Win32 Functions' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>


Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' rel='bookmark' title='Permanent Link: Calling Macro Scheduler Functions from PowerShell'>Calling Macro Scheduler Functions from PowerShell</a></li><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/' addthis:title='Creating Native Function Aliases for Win32 Functions'  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>The other day I <a href="http://www.mjtnet.com/usergroup/viewtopic.php?t=6549#29012">posted a response</a> on the forums which uses LibFunc to run the Win32 API function GetKeyState.  This prompted someone to email me the following:</p>
<blockquote><p>I didn&#8217;t know the Win API call to check for a key being down. The API call works but have you considered adding a native MS command called KeyDown> or maybe CheckKeyDown></p></blockquote>
<p>Well, it&#8217;s already possible to create native looking functions for DLL functions and therefore Win32 API functions.</p>
<p>We can do this by creating an Imports file in the Imports sub folder of Macro Scheduler.   Let&#8217;s make an import file for some functions in User32.dll:</p>
<p><strong>Step 1</strong>.  If you don&#8217;t already have an Imports subfolder inside the Macro Scheduler program folder, create one: c:\program files\Macro Scheduler12\Imports</p>
<p><strong>Step 2</strong>.  Create a symbolic link to the appropriate DLL in this folder.  Start a CMD prompt and CD to the Imports folder and for User32.dll type the following: </p>
<blockquote><p>mklink user32.dll c:\windows\system32\user32.dll</p></blockquote>
<p>If on a 64 bit system replace system32 with syswow64</p>
<p>This will create a link to the DLL in the Imports folder.  Next we need to make a corresponding INI file.</p>
<p><strong>Step 3</strong>.  Create a file called User32.ini in the Imports folder.  Inside this file create entries for each function you wish to import.  E.g.:</p>
<blockquote><p>[GetKeyState]<br />
FunctionName=GetKeyState<br />
Parms=1<br />
Parm1=INT</p>
<p>[SendMessage]<br />
Parms=4<br />
Parm1=INT<br />
Parm2=INT<br />
Parm3=INT<br />
Parm4=INT</p>
<p>[FindWindow]<br />
Parms=2<br />
Parm1=PCHAR<br />
Parm2=PCHAR</p></blockquote>
<p>Now, instead of writing:</p>
<pre name="code" class="macroscript">Let>VK_UP=38
LibFunc>user32,GetKeyState,result,VK_UP</pre>
<p>You can write:</p>
<pre name="code" class="macroscript">Let>VK_UP=38
GetKeyState>VK_UP,result</pre>
<p>So here&#8217;s a project for someone or a group of people:  Create a User32.ini file for a fuller list of compatible functions which we can share on the website.   Any function that accepts either integers (INT) or strings (PCHAR) and returns an integer (or nothing) can be included.  And then we want another one for Kernel32.dll &#8230; etc.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/' addthis:title='Creating Native Function Aliases for Win32 Functions' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>

<p>Related posts:<ol><li><a href='http://www.mjtnet.com/blog/2011/06/13/calling-macro-scheduler-functions-from-powershell/' rel='bookmark' title='Permanent Link: Calling Macro Scheduler Functions from PowerShell'>Calling Macro Scheduler Functions from PowerShell</a></li><li><a href='http://www.mjtnet.com/blog/2012/01/24/webrecorder-3-0-faster-more-reliable-more-functions/' rel='bookmark' title='Permanent Link: WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions'>WebRecorder 3.0 &#8211; Faster, More Reliable, More Functions</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mjtnet.com/blog/2010/11/15/creating-native-function-aliases-for-win32-functions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

