Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
Очистка памяти при выполнении макроса
 
Здравствуйте все.

Я разгадал причину с помощью Ваших простых примеров. Спасибо Вам огромное!!!
Проблема крылась не в работе Excel, а в обработке объекта json.
Во вложении приложил файл с json строкой, которая приходит от API, но думаю это особо и не к чему.

Вот как примерно выглядит обработка ответа:
Код
Dim oRequestList As Collection
Dim oRequest As ServerXMLHTTP60
Dim oResponse as Object
Dim oItem As Object
Dim oRow As Object
 
'создание асинхронных http-запросов и добавление их в oRequestList
 
For Each oRequest In oRequestList
    oRequest.waitForResponse
    Set oResponse = JsonConverter.ParseJson(oRequest.responseText)
 
    'обработка json ответа
    For Each oItem In oResponse("items")
        For Each oRow In oItem("rows")
         ' обработка строки
      Next oRow
   Next oItem
    Set oResponse = Nothing
Next oRequest

Как писал sokol92 "Память освобождается после завершения работы макросов VBA.", действительно, память не освобождается после выхода из цикла, но, позволю себе поправить sokol92'а, память освобождается после завершения работы не макроса, а процедуры/функции, уничтожая все данные, связанные с этой процедурой/функцией и на которые нет ссылок в других местах кода. Моя же проблема заключалась в том, что в коде я не создавал ссылку на массив объектов в цикле, а отдавал это каким-то внутренним силам VBA, в результате чего своими силами я не мог очистить память Nothing'ом. Память не очищалась при помощи Set oResponse = Nothing, потому что была ссылка на коллекцию oResponse("items").

Если создать переменную для такой коллекции и передавать ее в качестве коллекции для перебора, а после цикла по oResponse("items") присвоить ей Nothing, то память очищается при каждой итерации.
Пример:
Код
Dim oRequestList As Collection
Dim oRequest As ServerXMLHTTP60
Dim oResponse as Object
Dim oItem As Object
Dim oRow As Object
Dim oItems As Object
Dim oRows As Object

'создание асинхронных http-запросов и добавление их в oRequestList

For Each oRequest In oRequestList
    oRequest.waitForResponse
    Set oResponse = JsonConverter.ParseJson(oRequest.responseText)
 
    'обработка json ответа
    Set oItems = oResponse("items")
    For Each oItem In oItems
        Set oRows = oItem("rows")
        For Each oRow In oRows
            ' обработка строки
        Next oRow
    Next oItem
    Set oRows = Nothing
    Set oItems = Nothing
    Set oResponse = Nothing
Next oRequest

Многие, наверное, скажут, что как такое можно было не знать и не понимать, но я не знал :)
Очистка памяти при выполнении макроса
 
Файл конвертера.
Не думаю, что проблема в нем, в ответе действительно приходит немалый объем данных, в json-формате может занимать ~40 Мб.
Но если Вы подскажете конвертер с какими-либо преимуществами перед этим, буду благодарен.
Изменено: Дмитрий Г - 09.12.2020 12:39:34 (Добавлен файл во вложение)
Очистка памяти при выполнении макроса
 
Всем привет.

Столкнулся с проблемой нехватки памяти и решил, что я умнее всех и пытался очистить ее следующим образом: Set oResponse = Nothing. Но это не работает, оперативная память не освобождается, пока не произойдет выход из цикла. Пример кода:
Код
Dim oRequestList As Collection
Dim oRequest As ServerXMLHTTP60
Dim oResponse as Object

'создание асинхронных http-запросов и добавление их в oRequestList

For Each oRequest In oRequestList
    oRequest.waitForResponse
    Set oResponse = JsonConverter.ParseJson(oRequest.responseText)

    'обработка json ответа

    Set oResponse = Nothing
Next oRequest
Иногда json-ответ, преобразованный в структуру для VBA может занимать 400 и более Мб памяти, также количество запросов варьируется. Были случаи, когда суммарно Excel начинал "поедать" 8 Гб памяти, что может быть страшным для некоторых ПК. Строкой Set oResponse = Nothing я думал память, выделенная под json-ответ, высвобождается, но это не так. Она высвобождается автоматически, когда происходит выход из цикла, а хотелось бы поддерживать эти ~400 Мб занятой памяти на протяжении работы всего цикла. Это как-то возможно сделать?

Ну и на самом деле я все равно не верил, что это поможет, ведь каждую итерацию в oResponse присваивается ссылка на другой объект, что, по идее, должно уничтожать объект по предыдущей ссылке.
Отправка запроса к API с использованием сертификата
 
Нашлось решение. Все же использовал объект XMLHTTP60 для отправки запроса. Сначала отправил запрос с пустым телом, получил ошибку и после этого началась магия, скорее всего на стороне Яндекса. Но это лишь догадка человека, далекого от серверных и админских дел. После этих манипуляций запросы стали улетать корректно. Проверено на нескольких машинах, именно такие манипуляции приводят к успеху. Если есть знатоки, которые способны это объяснить, дайте знать причину такого поведения.
Отправка запроса к API с использованием сертификата
 
Цитата
Можно включить 1.1 / 1.2
Запускаю макрос на Windows 10 Pro с последними обновлениями. В справке майкрософта сказано, что, начиная с Windows 8, по умолчанию используются TLS 1.0, 1.1 и 1.2.
Цитата
Сертификат-то нужно?
В вашем коде ничего нет касательно сертификата
См. метод SetClientCertificate объекта WinHttpRequest
Пробовал .SetClientCertificate "LOCAL_MACHINE\Root\Certum", получаю ошибку "В сертификате клиента отсутствовали учетные данные.". Опять же из справки, можно указать только путь до хранилища сертификата без его имени, например, "LOCAL_MACHINE\Root\", нужный сертификат будет выбран автоматически. Так тоже пробовал, ошибка аналогичная.
В моем коде сертификат устанавливается строкой .Option(WinHttpRequestOption_SelectCertificate) = "LOCAL_MACHINE\Root\". Если раскомментить, ошибка аналогичная.

Все это время искал альтернативный способ, но увы, ограничиться только VBA не получается.
Нашел какое-то решение с использованием библиотеки WinInet, но в итоге выяснил, что https она не использует, только http или ftp.

У меня закончились идеи, я сдаюсь  :cry:  
Отправка запроса к API с использованием сертификата
 
Приветствую всех.

Возникла проблема с отправкой запроса к API Яндекс Директ.
Выложил ссылки на справку по Яндексу на всякий, потому что проблема возникает при отправке запросов именно к нему (в приложенном файле, а то местный антиспам не дает отправить сообщение). Тех. поддержка Яндекса может читать только общедоступную справку и давать консультации только теми словами, что уже и так написано в справке. Собственно они мне так и ответили, что если бы я писал на cURL или питоне, то они бы подсказали. Хотя я даже в этом случае сомневаюсь в их компетентности...
Попробовал отправить запросы этим же кодом к API Youtube, запрос улетел без капризов и был получен ответ.

При отправке запроса к API Яндекс Директ получаю следующие ошибки (в зависимости от опции WinHttpRequestOption_SecureProtocols):
  • при включенных SSL 2/3 - Ошибка 80072f7d: Ошибка поддержки безопасных каналов.
  • при включенном TLS 1.0 - Ошибка 80072f99: В сертификате клиента отсутствовали учетные данные.
По коду:
Строки с закомментированными опциями - все то, что я пробовал, чтобы запрос улетел.
Строки с закомментированными заголовками - все заголовки, которые были добавлены Rest Api Client'ом (кроме Host, это отсебятина). Основные, что требуются - это Authorization, Client-Login, Content-Type и Accept-Language.
Также пробовал использовать XMLHTTP2 v6.0 для отправки запроса, ошибки аналогичные, только их коды другие.

Возможно, Excel действительно не предназначен для таких запросов, но хочется верить, что все получится :)
Если есть замечания по обработке статусов http или еще чему, принимаю критику, но первостепенная задача - отправка запроса, а дальше уже гори оно огнем дело техники.

Скрытый текст
Страницы: 1
Наверх