Отправка и получение данных через POST в Microsoft Word 2011 для OSX

Я пытаюсь перенести макрос, который у нас работает, для MS Word на Windows, который использует веб-сайт для создания изображения уравнения и возвращает его для вставки в документ. Текущий (работающий на Windows) вызов ниже. Когда я использую тот же вызов в OSX, я получаю сообщение об ошибке 429, в котором говорится, что "компонент ActiveX не может создать объект".

' Create an xmlhttp object.
Set w_page = CreateObject("Microsoft.XMLHTTP")

' Open the connection to the remote server.
w_page.Open "POST", WebAdd, False

' Indicate that the body of the request contains form data
w_page.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

' Actually send the request and return the data:
Font_Size = ComboFontSize.Value
w_page.Send "formula=" & Font_Size & "." & Latex_Str

Ошибка генерируется на Set w_page = CreateObject("Microsoft.XMLHTTP") заявление. Я попробовал несколько альтернативных методов, таких как:

Set w_page = CreateObject("MSXML2.ServerXMLHTTP")

а также

Set w_page = CreateObject("WinHttp.WinHttpRequest.5.1")

Но та же ошибка генерируется. Пожалуйста, помогите мне найти правильный способ отправки POST в OSX Word 2011.

Для всех, кто заинтересован, проект доступен на GitHub.

Большое спасибо!

РЕДАКТИРОВАТЬ: я нашел этот пост, который подробно описывает вариант для использования с OSX Excel, но я не могу найти его аналог для OSX Word. Кто-нибудь знает Word-эквивалент Excel ActiveSheet.QueryTables что будет работать для отправки сообщений в OSX?

РЕДАКТИРОВАТЬ: я сделал некоторый прогресс. Похоже, что вы можете вызывать внешние программы через VBA, и все Mac поставляются с установленным Python, поэтому я написал скрипт на Python, который использует urllib а также urllib2 отправить запрос на сервер. Файл Python также использует argparse проанализировать строку формулы, размер шрифта и веб-адрес из командной строки.

Теперь мой макрос может вызывать мой скрипт на Python примерно так:

sCmd = "python " & pyPath & "getURL.py --formula " & Latex_Str & " --fontsize "_
    & Font_Size & " " & WebAdd
sResult = Shell(sCmd, vbNormalFocus)

куда Latex_Str вводится пользователем через приложение, Font_Size также определяется пользователем, и WebAdd является одним из двух адресов, в зависимости от того, генерируем ли мы уравнение или очищаем временные файлы.

Что я не могу понять, так это как заставить VBA прочитать результат из моего скрипта Python (строку с возвращаемыми значениями с моего сервера, которая мне нужна для последующего получения файла изображения). Shell Команда только возвращает номер PID. Кто-нибудь может помочь?

РЕШЕНИЕ: Я понял это! Мне удалось написать скрипт Python для обработки запроса POST к серверу и распечатать его ответ на стандартный вывод. С помощью сообщества и большого количества документации в Интернете, я смог вызвать этот скрипт на Python, используя AppleScript из VBA с result = vba.MacScript(command) метод. Это позволило мне прочитать стандартный вывод из моего скрипта Python в строковую переменную в VBA. Мой скрипт на Python был следующим:

# Import the required libraries
from urllib import urlencode
from urllib2 import Request, urlopen, URLError, ProxyHandler, build_opener, install_opener
import argparse

# Set up our argument parser
parser = argparse.ArgumentParser(description='Sends LaTeX string to web server and returns meta data used by LaTeX in Word project')
parser.add_argument('webAddr', type=str, help='Web address of LaTeX in Word server')
parser.add_argument('--formula', metavar='FRML', type=str, help='A LaTeX formula string')
parser.add_argument('--fontsize', metavar='SIZE', type=int, default=10, help='Integer representing font size (can be 10, 11, or 12. Default 10)')
parser.add_argument('--proxServ', metavar='SERV', type=str, help='Web address of proxy server, i.e. http://proxy.server.com:80')
parser.add_argument('--proxType', metavar='TYPE', type=str, default='http', help='Type of proxy server, i.e. http')

# Get the arguments from the parser
args = parser.parse_args()

# Define formula string if input
if args.formula:
    values = {'formula': str(args.fontsize) + '.' + args.formula}   # generate formula from args
else:
    values = {}

# Define proxy settings if proxy server is input.
if args.proxServ:       # set up the proxy server support
    proxySupport = ProxyHandler({args.proxType: args.proxServ})
    opener = build_opener(proxySupport)
    install_opener(opener)

# Set up the data object
data = urlencode(values)
data = data.encode('utf-8')

# Send request to the server and receive response, with error handling!
try:
    req = Request(args.webAddr, data)

    # Read the response and print to a file
    response = urlopen(req)
    print response.read()

except URLError, e:
    if hasattr(e, 'reason'):    # URL error case
        # a tuple containing error code and text error message
        print 'Error: Failed to reach a server.'
        print 'Reason: ', e.reason
    elif hasattr(e, 'code'):    # HTTP error case
        # HTTP error code, see section 10 of RFC 2616 for details
        print 'Error: The server could not fulfill the request.'
        print 'Error code: ', e.code
        # print e.read()

Эта связанная нить, которую я начал совсем недавно, указала мне в направлении MacScript команда для вызова моей функции и получения возврата строки, и @CuberChase заставил меня начать путь к написанию внешней функции для обработки вызова к серверу. Большое спасибо!

1 ответ

Решение

К сожалению, нет возможности выполнить запрос HTTP Post напрямую из VBA через Mac Office.

В настоящее время вы получаете сообщение об ошибке 429, в котором говорится, что "компонент ActiveX не может создать объект", поскольку в OS X нет объектной модели XMLHTTP (или MSXML2, или WinHttp), эти объектные модели предназначены только для Windows. Это означает, что они недоступны для любых программ Office, не только Word.

Вы должны будете найти обходной путь, например, используя AppleScript (не уверен, возможно ли это или нет) или выполнив команду оболочки для внешней программы, такой как curl. Этот SO-ответ использует Curl для HTTP-запроса Get и, вероятно, является лучшей отправной точкой.

Другие вопросы по тегам