Страницы: 1
RSS
Лучший парсер VBA-Json (ваше мнение)
 
Приветствую всех! Подскажите пожалуйста, какой по вашему мнению лучший парсер в связке VBA-Json?

Есть одно условие, с которым мне придется смириться к сожалению, не от меня зависит- в ответах Json время от времени будут попадаться в полях (в значениях полей ,выгружаемых в Json) символы типа таких: "  '  // / \ {}} .  и прочие кракозябры.
 
Лично моё мнение, лучший парсер это тот, который заточен под определённое место (сайт).
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
Да, в этот плане попроще, выводимый Json имеет четкую структуру, порядок и количество выводимых полей не меняется. Но присутствуют запрещенные /нерекомендуемые значки в самих значениях: "  '  // / \ {}} И их как то надо обработать.
C VBA уже достаточно давно ,больше 10 лет,проблем нет, прошу подсказать самый крутой по вашему мнению парсер VBA -> Json (Можно в виде класса, функции, чего угодно) Ключевое требование, чтобы мог справляться с нестандартными данными в значениях выводимых полей в Json.
 
Можно так:
Код
' Кодирует скалярный аргумент в Json, заключает текст в двойные кавычки
Public Function JsonEncode(ByVal p_s) As String
    Dim s As String, i As Long, i2 As Long, n As Long
    Select Case VarType(p_s)
        Case vbNull
            s = "null"
      
        Case vbBoolean
            s = IIf(p_s, "true", "false")
      
        Case vbByte, vbCurrency, vbDecimal, vbDouble, vbInteger, vbLong, vbSingle
            s = Replace(CStr(p_s), ",", ".")
            
        Case Else
            s = """" & Replace(Replace(Replace(Replace(p_s, "\", "\\"), """", "\"""), Chr(10), "\n"), "/", "\/") & """"
  
            ' проверяем символы 0-31 и кодируем их
            i = 2
            i2 = Len(s) - 1
            While i <= i2
                n = Asc(Mid(s, i, 1))
                If n <= 31 Then ' меняем n на \uHHHH, увеличиваем длину на 5 символов
                    s = Mid(s, 1, i - 1) & "\u00" & IIf(n <= 15, "0", "") & Hex(n) & Mid(s, i + 1)
                    i = i + 5
                    i2 = i2 + 5
                End If
    
                i = i + 1
            Wend
    End Select
    JsonEncode = s
End Function
Владимир
 
sokol92,

Отлично, спасибо! Сейчас потестим и ваш вариант :idea:
Но ваш пример это функция encode , то есть вывода данных к примеру с листа экселя и передачу его к примеру на сервер.)

Парсер это наоборот-когда вы декодируете сообщение , получаемое из определенного источника (в частности с сайта, или текстового источника.)
Изменено: Лалыч - 20.09.2019 16:08:40
 
Цитата
Лалыч написал:
мог справляться с нестандартными данными в значениях выводимых полей в Json.
Я это понял так. :)

Что касается парсеров JSON, то, на мой взгляд, наиболее продвинутый вариант (из опубликованных) у Tim Hall - https://github.com/VBA-tools/VBA-JSON.
Владимир
 
Да, спасибо,видал) Это самая большая и проработанная библиотека в плане парсинга json. Там есть все возможные сценарии и возможность создать любой шаблон. Но она при определенных условиях подлипает и замедляет работу приложения (Что в экселе,что в аксессе. В Экселе при большом количестве записей начинает тупить безбожно. В аксессе ситуация по скорости процентов на 25-30 получше, но тоже не нравиться.) Возможно удастся немного подпилить, работаю над этим)

Во время поисков библиотек параллельно нашел самый краткий и простой формат обработки json. Вот ,могу поделиться, для экселя как раз идеально подходит. На русскоязычных сайтах не нашел, на одном зарубежном . Все гениальное просто, всего семь строк самого парсера. Он не обрабатывает по умолчанию проблемные значения в Json, но приятен с позиции восприятия программиста VBA . В принципе я его подточил немного, вот код:
Код
Private Sub CommandButton1_Click()
' ВЫВОДИТ JSON В ЯЧЕЙКИ EXCEL
Dim str As Variant, N&, R&
Dim xmlhttp As New MSXML2.XMLHTTP60 ' не забудьте подключить в библиотеках ' tools -> references
Dim URL As String
Dim user As String
Dim password As String

user = Cells(6, "H") 'ячейка для ввода логина
password = Cells(7, "H") 'ячейка для ввода пароля
URL = "http://localhost/json_test/simpleJson.php"  ' путь до страницы ,где выводится json

If user = "" Or password = "" Then
MsgBox "Заполните поля логин и пароль"
Exit Sub
End If

argumentString = "user=" & user & "&password=" & password

        xmlhttp.Open "POST", URL, False ' открываем соединение
        xmlhttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded" '
        xmlhttp.send argumentString
        'MsgBox xmlhttp.responseText, vbInformation, "ЭТО ВЫВОД СЫРОГО JSON НА ЭКРАН! НАЖМИТЕ ОК.
  ' НАЧАЛО ПАРСЕРА
        str = Split(xmlhttp.responseText, "{""client_id"":") 'client_id - имя ключевого поля из таблицы, первое, с чего начинается само тело Json
    N = UBound(str)
    For R = 1 To N
        Cells(R + 1, 1) = Split(Split(str(R), "company_name"":""")(1), """")(0) ' R+1 - выгрузка в ячейки начинается со второй строки
        Cells(R + 1, 2) = Split(Split(str(R), "telefone"":""")(1), """")(0)
        Cells(R + 1, 3) = Split(Split(str(R), "e_mail"":""")(1), """")(0)
    Next R
    ' КОНЕЦ ПАРСЕРА
    
    
Exit Sub
10: MsgBox Err.Description
End Sub


И написал под него небольшой тестовый код PHP на стороне веб сервера (выгрузка происходит из небольшой тестовой таблицы в базе на MySQL):

Код
<?php

if (empty($_POST['user']) || empty($_POST['password']))  
{
echo "Заполните поля логин и пароль!";  
} 
else 
{
    $log= $_POST['user'];
    $pass=$_POST['password'];
    
   try {
     $dbh = new PDO('mysql:host=localhost;charset=utf8;dbname=test_db', $log, $pass);
     $response = $dbh->query("SELECT * FROM tbl_clients")->fetchAll(PDO::FETCH_ASSOC);
    
    foreach ($response as $row)
        {
        print json_encode($row,JSON_UNESCAPED_UNICODE);  
        }
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage();
   // die();
}

  }
?>
Изменено: Лалыч - 20.09.2019 17:46:31
 
Цитата
Лалыч написал:
она при определенных условиях подлипает и замедляет работу приложения
Да, это так, поскольку для хранения данных объектов JSON динамически создаются словари, что, естественно, не эффективно при большом количестве объектов.
Мы используем для разбора JSON собственный скорострельный потоковый парсер (для посимвольного анализа JSON применяя фрагмент кода из процитированной ссылки).

Вместе с тем следует признать, что создание высокоэффективных универсальных внутренних структур VBA для хранения объектов и массивов JSON является не простой задачей.
Владимир
 
Цитата
Alemox написал:  лучший парсер это тот, который заточен под определённое место (сайт).
поэтому при смене структуры подачи инфо на сайте - надо переделывать...
самый лучший - тот, в который минимум переделок надо вносить - т.е. легко сопровождать...
===
#4 и #7 - тупо разбор строки...
можно регулярное выражение написать любое из таких частей -
Код
RegExp.Pattern = "" & Chr(34) & "(.+?)" & Chr(34) & ":(.+?),"   'берёт каждый элемент (key & item) отдельно

и соотв. код для выгрузки
- при изменении подачи инфо на сайте - просто менять регулярку...
самый лучший - это самый простой... имхо
===
есть JsonBag класс (есть примеры на сайте) - кода больше, но работает под win32 т.к., насколько помню, написан на ScriptControl reference'e,
в win64 - ScriptControl нет, для win64 - где-то в сети был класс на регулярках... но всё равно хоть с классом, хоть без, а код писать придётся... поэтому, как указала выше, - сделайте универсальный код для RegExp json-структуры -- и используйте, внося минимальные правки в паттерн при изменениях источника...
===
а самый простой - это Power Query !! без vba ... ничто с ним в сравнение не идёт...
Изменено: JeyCi - 20.09.2019 19:19:12
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Большое спасибо всем за ответы!

Цитата
JeyCi написал:
а самый простой - это Power Query !! без vba ... ничто с ним в сравнение не идёт...
Power Query безусловно волшебная палочка, но к сожалению (очень и очень большому) в MS Access её не завезли. Хоть сам собирай народ и выходи на митинг около главного здания Майкрософт,с просьбой включить PQ в состав MS Access ))


Цитата
sokol92 написал:
Мы используем для разбора JSON собственный скорострельный потоковый парсер (для посимвольного анализа JSON применяя фрагмент кода из процитированной ссылки).
Есть даже отдельные сервера , которые только и заточены под это)

В общем еще раз огромное спасибо за участие в обсуждении, буду экспериментировать, материала собрал много.
 
Цитата
Лалыч написал: в MS Access её не завезли
делать C++ надстройку или подключаемую библиотеку для Access - в Ultimate++ уже есть соотв библы для парсинга json ... или на C# делать на Newtonsoft.dll (он же JSON.NET)...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
sokol92, благодарю Вас за ссылку!
Страницы: 1
Наверх