Макрос vbs. Метод. Запуск объекта «IWshShell3» завершился неудачно, только захлестывает большие файлы Word.

Я действительно новичок в VBA. Я вставил только последнюю часть этой подпрограммы, но могу выложить остальные, если это поможет. Был бы признателен за любую помощь. Я искал несколько дней, но большинство проблем с этой ошибкой вызваны пробелами в имени пути. Спасибо дополнительно!

Этот макрос читает заголовок, затем каждую таблицу в открытом документе Word, затем записывает каждую строку в переменную htmlFile. Затем он запускает файл PowerShell ps1, который записывает файл HTML в путь сохранения.

Отлично работает с небольшими документами Word, но когда я запускаю его с большими, я получаю эту ошибку:

Ошибка выполнения "-2147024690 (800700ce)": сбой метода "Выполнить" объекта "IwshShell3"

Код (все в Sub до этого бита читало каждую таблицу в открытом документе Word и записывало в htmlFile как HTML-код):

Sub WriteHtml()
    Dim htmlFile AS String, strText As String

    '
    ' fill htmlFile with HTML code ...

    htmlFile = htmlFile & strText

    Dim pwFileLocation, htmlFileLocation As String
    pwFileLocation = "'O:\Docketbk\DocketToWeb\processFile.ps1'"

    'htmlFileLocation = "'W:" & stringSplits(1) & "'"
    htmlFileLocation = "'Q:\OIT\Web Sites\This Site\Regulatory\Docketbk\" & stringSplits(1) & "'"
    fileNameFinal = Left(ActiveDocument.Name, InStrRev(ActiveDocument.Name, ".") - 1) & ".html"

    Dim shell, command1
    command1 = "powershell -noexit -command powershell.exe -Executionpolicy Bypass -File " & pwFileLocation & "-htmlContent ""'" & htmlFile & """' -savePath " & htmlFileLocation & " -fileName """ & fileNameFinal & """"
    Set shell = CreateObject("WScript.Shell")
    shell.Run command1, 1

End Sub

КОД POWERSHELL:

param(
   [string] $htmlContent,
   [string] $savePath,
   [string] $fileName
)
$fullFilePath = $savePath + "\" + $fileName 

Function CreateHtmlFile()
{
        if (!(Test-Path -Path $fullFilePath)){
            New-Item  $fullFilePath -ItemType File
            WriteHtmlFile       
        } else {
             WriteHtmlFile
        }
}
Function WriteHtmlFile()
{
        Set-Content $fullFilePath $htmlContent.Replace('$DubQ','"')     
}
createHtmlFile

КОД ПЕРЕМЕЩЕНИЯ POWERSHELL:

param(
   [string] $oldFileLocation,
   [string] $newFileLocation
)

net use W: \\MYSERVERNAME\Websites\PUC\Regulatory\Docketbk

Function MoveFile
{
    $moveDirectory = $oldFileLocation + "/*" 
    Copy-Item -Path $MoveDirectory  -Destination $newFileLocation -Container -Recurse -force
}

MoveFile

person Bullseye    schedule 13.01.2020    source источник
comment
Комментарии не для расширенного обсуждения; этот разговор был перенесено в чат.   -  person Samuel Liew♦    schedule 15.01.2020


Ответы (1)


Я сторонник простоты. И большинство (если не все) ваших проблем возникают из-за того, что не соблюдаете простоты. У вас слишком много движущихся частей, слишком много уровней косвенности. Вы можете попытаться решить эту проблему, поработав над этим еще немного, и вы можете попытаться упростить свой подход.

Все, что вы делаете — создание строки HTML, запись ее в файл, копирование папок — можно выполнить в коде VBA. Я не вижу ничего, что потребовало бы PowerShell.

Для операций с файловой системой Scripting.FileSystemObject очень удобен, и следующий код использует его. Давайте сделаем это доступным, ссылаясь на библиотеку "Microsoft Scripting Runtime" через меню Tools References в VBA IDE.

Теперь у нас есть две основные операции: создание HTML из исходного документа и запись заданного текста в файл.

Dim FSO As New Scripting.FileSystemObject

Function CreateHtml(sourceDoc As Document) As String
    ' Creates HTML from the tables of the given document.
    Dim html As String, text As String

    ' ... build html from sourceDoc
    html = html & text

    CreateHtml = html
End Function

Sub WriteTextToFile(content As String, path As String, Optional fileName As String)
    ' Writes a string to a Unicode file. Target will be overwritten if it exists.
    Dim targetPath As String

    If fileName > "" Then
        targetPath = FSO.BuildPath(path, fileName)
    Else
        targetPath = path
    End If

    With FSO.CreateTextFile(fileName:=targetPath, overwrite:=True, unicode:=True)
        .Write content
    End With
End Sub

И теперь мы можем объединить их в Sub, который я назвал HtmlWorkflow, за неимением лучшего имени:

Sub HtmlWorkflow()
    Dim stringSplits As Variant, html as String

    stringSplits = Split("something", "delimiter")
    html = CreateHtml(sourceDoc:=ActiveDocument)

    WriteTextToFile _
        content:=html, _
        path:="Q:\OIT\Web Sites\This Site\Regulatory\Docketbk\" & stringSplits(1), _
        fileName:=FSO.GetBaseName(ActiveDocument.Name) & ".html" _

    FSO.CopyFolder _
        Source:="Q:\whatever\your\source\folder\path\is", _
        Destination:="\\whatever\your\destination\folder\path\is"
End Sub

Примечания:

  • Я использую именованные параметры в своих вызовах функций - это может сохранить некоторые временные переменные и делает вещи в основном самодокументируемыми.
  • _ в конце строки является символом продолжения строки VB. Его использование облегчает чтение длинных строк кода.
  • Разделение на отдельные функции упрощает отладку и тестирование (теперь вы можете вызывать CreateHtml() для любого открытого документа, независимо от того, активен он или нет) и упрощает повторное использование (WriteTextToFile не важно, какой файл или какое содержимое) .
  • Документация для FileSystemObject находится здесь: https://docs.microsoft.com/en-us/office/vba/language/reference/objects-visual-basic-for-applications
person Tomalak    schedule 13.01.2020
comment
Вау, это выглядит намного чище. Мне просто нужно немного времени, чтобы обдумать это и правильно настроить источник / место назначения папок. Также неясно о строке stringSplits. Большое спасибо. Утром постараюсь все это установить. - person Bullseye; 13.01.2020
comment
Ну, я придумал эту строку, потому что в вашем коде использовалось stringSplits(1), и вы никогда не показываете, что это такое. Я подумал, что это должна быть какая-то операция разделения строк, поэтому я вставил фиктивный вариант. - person Tomalak; 13.01.2020
comment
Смущен тем, куда идет функция CreateHtml. Разве это не должно быть в сабе? Как я уже сказал, это почти иностранный язык, и моя версия была собрана с большим трудом. Я чувствую, что я рядом. Причина, по которой я даже сделал это построчно, заключалась в том, чтобы очистить все мусорные HTML-теги Word. Создает ли ваш способ чистый HTML? Еще раз спасибо за помощь. - person Bullseye; 14.01.2020
comment
Создайте новый модуль в VBA IDE и поместите туда две функции из первого фрагмента кода. Или поместите их в тот же модуль, где находится ваш текущий код. - person Tomalak; 14.01.2020
comment
... мой второй фрагмент кода показывает, как предполагается использовать функцию CreateHtml(). Это должен быть Function, потому что он возвращает значение — строку HTML — и только функции могут иметь возвращаемые значения в VBA. - person Tomalak; 14.01.2020
comment
Очистить HTML-код, созданный Word, не так-то просто. Если у вас эта часть работает, оставьте ее. - person Tomalak; 14.01.2020
comment
...Хм? Как должен работать второй блок кода, когда он вызывает функции из первого блока кода? (Не копируйте и не вставляйте мой код вслепую. Прочтите и поймите, что он делает. Вам нужно понять каждую строку кода, которую вы не написали сами, прежде чем использовать ее. Копирование кода, который вы не понимаете, опасно.) - person Tomalak; 14.01.2020