<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; WSH: преобразуем макрос VBA в скрипт VBScript]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=5675</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=5675&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «WSH: преобразуем макрос VBA в скрипт VBScript».]]></description>
		<lastBuildDate>Thu, 12 May 2011 07:54:28 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: WSH: преобразуем макрос VBA в скрипт VBScript]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=48324#p48324</link>
			<description><![CDATA[<p><strong>2 alexii:</strong> Почитал. Взгрустнулось....:rolleyes: Вот найти бы способ отдельно от [Word / Excel] Application выполнять макросы VBA... Мечты мечты..</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Thu, 12 May 2011 07:54:28 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=48324#p48324</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: преобразуем макрос VBA в скрипт VBScript]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=48297#p48297</link>
			<description><![CDATA[<p>Спасибо за статью. Имеет ли смысл работать в направлении создания переводчика из VBA в VBS и наоборот?</p>]]></description>
			<author><![CDATA[null@example.com (JSmаn)]]></author>
			<pubDate>Tue, 10 May 2011 19:59:26 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=48297#p48297</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: преобразуем макрос VBA в скрипт VBScript]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47191#p47191</link>
			<description><![CDATA[<p>Рассмотрим практический пример переноса макроса, записанного макрорекордером в приложении <strong>Microsoft Office</strong>, в скрипт <strong>Windows Script Host</strong>.</p><p>Например, откроем документ <strong>Microsoft Excel</strong>, выделим всю использованную область на первом рабочем листе, установим для выделенной области выравнивание и шрифт текста, сменим фон ячеек, отпечатаем два экземпляра рабочего листа, сохраним и закроем документ.</p><p>Запускаем <strong>Microsoft Excel</strong>, в меню <strong>Сервис</strong> выбираем пункт <strong>Макрос</strong>, затем <strong>Начать запись</strong>. В появившемся диалоговом окне <strong>Запись макроса</strong> убеждаемся, что в списке <strong>Сохранить в:</strong> указано <strong>Эта книга</strong>, нажимаем <strong>OK</strong>. Запись макроса началась.</p><p>Откроем документ «Hello World.xls» из папки «C:\Temp». Выделим всю использованную область первого рабочего листа. Для этого перейдём в первую ячейку (<strong>Ctrl-Home</strong>), затем выделим все ячейки, вплоть до последней использованной (удерживая <strong>Shift</strong>, нажимаем <strong>Ctrl-End</strong>). установим для выделенной области выравнивание текста в ячейках (<strong>Формат</strong>, <strong>Ячейки…</strong>): по горизонтали — по левому краю, по вертикали — по центру. Фон ячеек зададим светло-голубой. Поменяем шрифт выделения на «Verdana». Отпечатаем два экземпляра рабочего листа. Сохраним документ и закроем его. Остановим запись (<strong>Сервис</strong>, <strong>Макрос</strong>, <strong>Остановить запись</strong>).</p><p>Теперь откроем редактор <strong>VBA</strong> (<strong>Сервис</strong>, <strong>Макрос</strong>, <strong>Редактор Visual Basic</strong>). В окне проекта (<strong>View</strong>, <strong>Project Explorer</strong>) откроем наш проект (<strong>VBAProject (Книга1)</strong>), в нём последовательно раскроем <strong>Modules</strong>, <strong>Module1</strong> и посмотрим текст записанного макроса:<br /></p><div class="codebox"><pre><code>Option Explicit

Sub Макрос1()
&#039;
&#039; Макрос1 Макрос
&#039; Макрос записан 31.03.2011 (UserName)
&#039;
&#039;
    ChDir &quot;C:\Temp&quot;
    Workbooks.Open Filename:=&quot;C:\Temp\Hello World.xls&quot;
    Range(&quot;A1&quot;).Select
    Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select
    With Selection
        .HorizontalAlignment = xlLeft
        .VerticalAlignment = xlCenter
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    With Selection.Font
        .Name = &quot;Verdana&quot;
        .FontStyle = &quot;обычный&quot;
        .Size = 10
        .Strikethrough = False
        .Superscript = False
        .Subscript = False
        .OutlineFont = False
        .Shadow = False
        .Underline = xlUnderlineStyleNone
        .ColorIndex = xlAutomatic
    End With
    With Selection.Interior
        .ColorIndex = 20
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
    End With
    ActiveWindow.SelectedSheets.PrintOut Copies:=2, Collate:=True
    ActiveWorkbook.Save
    ActiveWorkbook.Close
End Sub</code></pre></div><p>Скрипт <strong>Windows Script Host</strong>, основанный на данном макросе, может выглядеть так:<br /></p><div class="codebox"><pre><code>Option Explicit

Const xlLeft   = &amp;HFFFFEFDD
Const xlCenter = &amp;HFFFFEFF4

Dim objExcel


Set objExcel = WScript.CreateObject(&quot;Excel.Application&quot;)

With objExcel
    With .Workbooks.Open(&quot;C:\Temp\Hello World.xls&quot;)
        With .Sheets.Item(1)
            With .UsedRange
                .HorizontalAlignment = xlLeft
                .VerticalAlignment   = xlCenter
                
                .Font.Name           = &quot;Verdana&quot;
                .Interior.ColorIndex = 20
            End With
        
            .PrintOut , , 2
        End With
        
        .Save
        .Close
    End With
    
    .Quit
End With

Set objExcel = Nothing

WScript.Quit 0</code></pre></div><p>Рассмотрим процесс преобразования.</p><p>Для работы с объектом — его сначала нужно создать:<br /></p><div class="codebox"><pre><code>Set objExcel = WScript.CreateObject(&quot;Excel.Application&quot;)</code></pre></div><p>Далее, везде где можно, используем оператор <strong>With…End With</strong> (в том числе и вложенные), чтобы сократить код и время исполнения скрипта:<br /></p><div class="codebox"><pre><code>With objExcel
    With .Workbooks…</code></pre></div><p>Открытие документа в макросе:<br /></p><div class="codebox"><pre><code>    ChDir &quot;C:\Temp&quot;
    Workbooks.Open Filename:=&quot;C:\Temp\Hello World.xls&quot;</code></pre></div><p>преобразуем в скрипте в непосредственное указание документа для открытия:<br /></p><div class="codebox"><pre><code>With objExcel
    With .Workbooks.Open(&quot;C:\Temp\Hello World.xls&quot;)</code></pre></div><p>Переходы и выделение в макросе:<br /></p><div class="codebox"><pre><code>    Range(&quot;A1&quot;).Select
    Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select</code></pre></div><p>преобразуем в скрипте в непосредственное указание использованного диапазона ячеек посредством свойства рабочего листа <strong>.UsedRange</strong>:<br /></p><div class="codebox"><pre><code>        With .Sheets.Item(1)
            With .UsedRange</code></pre></div><p>Из множества записанных макрорекордером свойств:<br /></p><div class="codebox"><pre><code>    With Selection
        .HorizontalAlignment = xlLeft
        .VerticalAlignment = xlCenter
        .WrapText = False
        .Orientation = 0
        …</code></pre></div><p>берём только те, которые мы меняли:<br /></p><div class="codebox"><pre><code>                .HorizontalAlignment = xlLeft
                .VerticalAlignment   = xlCenter
                
                .Font.Name           = &quot;Verdana&quot;
                .Interior.ColorIndex = 20</code></pre></div><p>Использованные константы Microsoft Excel, как и было сказано в первом посте этой темы, перечисляем в начале скрипта:<br /></p><div class="codebox"><pre><code>Const xlLeft   = &amp;HFFFFEFDD
Const xlCenter = &amp;HFFFFEFF4</code></pre></div><p>Вывод на печать:<br /></p><div class="codebox"><pre><code>    ActiveWindow.SelectedSheets.PrintOut Copies:=2, Collate:=True</code></pre></div><p>преобразуется по правилам, указанным в первом посте этой темы — убираем именованные параметры, вместо них используем позиционные согласно прототипу метода:<br /></p><div class="quotebox"><blockquote><p><strong>PrintOut Method</strong></p><p><em>expression</em>.PrintOut(From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName)</p></blockquote></div><p>необязательные параметры не указываем:<br /></p><div class="codebox"><pre><code>            .PrintOut , , 2</code></pre></div><p>При сохранении и закрытии рабочей книги работаем именно с ней:<br /></p><div class="codebox"><pre><code>    With .Workbooks.Open(&quot;C:\Temp\Hello World.xls&quot;)
        …
        .Save
        .Close
    End With</code></pre></div><p>а не просто с активной рабочей книгой, как записал макрорекордер <strong>VBA</strong>.</p><p>Закрываем приложение и очищаем объектную переменную:<br /></p><div class="codebox"><pre><code>…
    .Quit
End With

Set objExcel = Nothing</code></pre></div><p>В формате *.wsf скрипт будет выглядеть практически так же:<br /></p><div class="codebox"><pre><code>&lt;?XML version=&quot;1.0&quot; standalone=&quot;yes&quot; encoding=&quot;windows-1251&quot; ?&gt;
&lt;job id=&quot;Hello World&quot;&gt;
    &lt;?job error=&quot;True&quot; debug=&quot;True&quot; ?&gt;
    &lt;runtime&gt;
        &lt;description&gt;Example of conversion VBA macros to WSH script&lt;/description&gt;
    &lt;/runtime&gt;
    
    &lt;reference guid=&quot;{00020813-0000-0000-C000-000000000046}&quot; /&gt;
    &lt;object id=&quot;objExcel&quot; progid=&quot;Excel.Application&quot; /&gt;
    
    &lt;script language=&quot;VBScript&quot;&gt;
        &lt;![CDATA[
            Option Explicit
            
            With objExcel
                With .Workbooks.Open(&quot;C:\Temp\Hello World.xls&quot;)
                    With .Sheets.Item(1)
                        With .UsedRange
                            .HorizontalAlignment = xlLeft
                            .VerticalAlignment   = xlCenter
                            
                            .Font.Name           = &quot;Verdana&quot;
                            .Interior.ColorIndex = 20
                        End With
                        
                        .PrintOut , , 2
                    End With
                    
                    .Save
                    .Close
                End With
                
                .Quit
            End With
            
            WScript.Quit 0
        ]]&gt;
    &lt;/script&gt;
&lt;/job&gt;</code></pre></div><p>но с б<em>о</em>льшими удобствами, как-то:<br /> * объект <strong>objExcel</strong> может быть создан при помощи тэга <strong><a href="http://forum.script-coding.com/viewtopic.php?pid=8844#p8844">object</a></strong>;<br /> * поскольку можно задать ссылку на библиотеку типов посредством тэга <strong><a href="http://forum.script-coding.com/viewtopic.php?id=1149">reference</a></strong> — не требуется явно описывать константы.</p>]]></description>
			<author><![CDATA[null@example.com (alexii)]]></author>
			<pubDate>Thu, 31 Mar 2011 02:31:20 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47191#p47191</guid>
		</item>
		<item>
			<title><![CDATA[WSH: преобразуем макрос VBA в скрипт VBScript]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47190#p47190</link>
			<description><![CDATA[<p>При автоматизации Microsoft Office средствами Windows Script Host довольно часто бывает проще записать макрос непосредственно в самом приложении Microsoft Office, а затем перенести текст полученного макроса Visual Basic for Apllication в скрипт Windows Script Host. Как правильно осуществить этот перенос?</p><p><em>Далее упоминания об использовании обычного скрипта *.vbs обозначены как <strong>VBS</strong>, об использовании формата скрипта *.wsf (<a href="http://forum.script-coding.com/viewtopic.php?id=1149">WSH: пишем сценарии в формате WSF</a>) — как <strong>WSF</strong>.</em></p><br /><p><strong>1. Константы</strong></p><p>При переносе констант Microsoft Office в скрипт Windows Script Host нужно помнить следующее:</p><p><strong>VBS</strong>: нужно вручную описать все используемые константы посредством ключевого слова <strong>Const</strong>.<br /><strong>WSF</strong>: достаточно добавить тэг <strong><a href="http://forum.script-coding.com/viewtopic.php?id=1149">reference</a></strong>, либо же использовать методику, изложенную в предыдущем пункте.</p><p><strong>2. Оператор «:=», именованные и необязательные аргументы</strong></p><p>Оператор «:=» присваивания значения некоторому параметру метода (используемый в макросах VBA для сокращения записи, когда задаются значения не всех параметров, либо параметры перечисляются в порядке, отличающемся от заданного прототипом) в <strong>Windows Script Host</strong> не поддерживается, поскольку <strong>Windows Script Host</strong> не поддерживает именованные аргументы, а только позиционные. Посему требуется убрать наименования аргументов (вместе с оператором «:=») и расставить аргументы в правильную позицию, так, как это описано в объектной модели того или иного метода или события. В большинстве случаев при работе с приложениями Microsoft Office необязательные аргументы допускается просто пропускать.</p><p><strong>3. Глобальные объекты, раннее и позднее связывание</strong></p><p>В глобальном контексте приложения <strong>Microsoft Office</strong> обычно наличествуют один или более глобальных объектов, таких, как объект Apllication целевого приложения, объекты CommandBars, FileDialog, Scripts (и т.д.) объектной модели самого <strong>Microsoft Office</strong>, объект UserForms объектной модели Visual Basic for Apllication. Ссылки на библиотеки, реализующие поддержку этих объектов изначально присутствуют в свойствах проекта VBA (<strong>\Tools\References…</strong>). В отличие от VBA, поддерживающего как раннее, так и позднее связывание, Windows Script Host поддерживает только позднее связывание при создании объектов. Исходя из вышеизложенного, надо помнить, что любой глобальный объект <strong>Microsoft Office</strong> требует явного предварительного создания перед использованием, как правило, завершения работы приложения методом «.Quit()» и очистки объектной переменной путём присвоения ей значения <strong>Nothing</strong>.</p><p><strong>VBS</strong>:<br /></p><div class="codebox"><pre><code>Set &lt;Var&gt; = WScript.CreateObject(&quot;&lt;ProgID&gt;&quot;)
…
&lt;Var&gt;.Quit
Set &lt;Var&gt; = Nothing</code></pre></div><p><strong>WSF</strong>: объект может быть создан при помощи тэга <strong><a href="http://forum.script-coding.com/viewtopic.php?pid=8844#p8844">object</a></strong>, либо может быть использована та же методика, что и для <strong>VBS</strong>.</p><p><em><strong>Замечание:</strong> последний способ не рекомендуется использовать для <strong>Microsoft Word</strong>, ибо может возникать ситуация (при вызове скрипта *.wsf с параметром «/?», чтобы посмотреть справку скрипта), когда приложение останется в памяти после завершения работы скрипта. Особенности поведения приложений <strong>Microsoft Office</strong> при использовании технологии Automation изложены в <strong>KB288902</strong>: <a href="http://support.microsoft.com/kb/288902">GetObject and CreateObject behavior of Office automation servers</a>, в частности:<br /></p><div class="quotebox"><blockquote><p><strong>Note</strong> For Word, the UserControl property is read-only. It cannot be set to True or False. Word always remains running when the last reference is released.</p></blockquote></div><p>Поэтому для <strong>Microsoft Word</strong> рекомендуется использовать методику, описанную в предыдущем пункте — непосредственное создание объекта в коде и завершение его методом «.Quit()».</em></p><p><strong>4. Обработка событий</strong></p><p>Поддержка обработки событий в <strong>Windows Script Host</strong> для объектов <strong>Microsoft Office</strong> осуществляется стандартными способами.</p><p><strong>VBS</strong>:<br /></p><div class="codebox"><pre><code>Set &lt;Var&gt; = WScript.CreateObject(&quot;&lt;ProgID&gt;&quot;, &quot;&lt;Prefix&gt;&quot;)
…
Sub &lt;Prefix&gt;&lt;Event&gt;(&lt;Argument List&gt;)
    …
End Sub</code></pre></div><p>либо же:<br /></p><div class="codebox"><pre><code>Set &lt;Var&gt; = WScript.CreateObject(&quot;&lt;ProgID&gt;&quot;)

WScript.ConnectObject &lt;Var&gt;, &quot;&lt;Prefix&gt;&quot;
…
WScript.DisconnectObject &lt;Var&gt;</code></pre></div><p><strong>WSF</strong>: можно добавить атрибут <strong><a href="http://forum.script-coding.com/viewtopic.php?pid=9591#p9591">events</a></strong> со значением «true» в тэг «object». Кроме того, поддерживается использование методики, описанной в предыдущем пункте.</p><p><em><strong>Замечание:</strong> к сожалению, большую часть событий приложений Microsoft Office обрабатывать не удаётся.</em></p>]]></description>
			<author><![CDATA[null@example.com (alexii)]]></author>
			<pubDate>Thu, 31 Mar 2011 00:12:37 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47190#p47190</guid>
		</item>
	</channel>
</rss>
