AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.09.2013, 10:16   #1  
Albeit is offline
Albeit
Участник
 
9 / 10 (1) +
Регистрация: 06.09.2013
Здравствуйте.
Такая задача.
Переменная Auda типа Automation, имеет ряд функций, которые при вызове с определенными параметрами возвращает Xml код,
содержащий список запрошенных данных - Тип: Строка (Unicode).
Требуется сохранить полученные данные в файл формата Xml для дальнейшего использования.
Пробовал делать так.

CREATE(Auda);
CREATE(XMLDoc);
XMLDoc.loadXML(Auda.GetTaskList('Логин','Пароль','Начальная дата','Конечная дата','OPENED'));
XMLDoc.save('c:\TempAuda.xml');

Переменные
Name DataType Subtype
Auda Automation 'Auda'.Saxif
XMLDoc Automation 'Microsoft XML, v6.0'.DOMDocument

Когда полученные данные из функции не превышают размер строки 1024, файл сохраняется.
Если данные превышают размер 1024, то Navision выдает сообщение "длина текстовой строки превосходит размер буфера строки".
Опыта работы с Хml в Navision нет. Подскажите пожалуйста, как решить задачу.
Старый 06.09.2013, 10:40   #2  
Constantine_imported is offline
Constantine_imported
Участник
 
126 / 10 (1) +
Регистрация: 28.04.2011
А в каком месте выскакивает ошибка? Подозреваю что на строке:
Код:
XMLDoc.loadXML...
т.к. если навставлять в XMLDoc кучу нод, то XMLDoc.save отрабатывает нормально и создает большие XML файлы без проблем.

Если функция Auda.GetTaskList на выходе дает готовый XML, может стоит попробовать читать данные потоком, а потом сохранить в файл?
Старый 06.09.2013, 11:08   #3  
Albeit is offline
Albeit
Участник
 
9 / 10 (1) +
Регистрация: 06.09.2013
Да, Ошибка на XMLDoc.loadXML...
Создавал переменную InStr типа InStream.

InStr:=Auda.GetTaskList('Логин','Пароль','Начальная дата','Конечная дата','OPENED')
XMLDoc.load(InStr);
XMLDoc.save('c:\TempAuda.xml');
При компиляции navision выдает ошибку "присваивание этой переменной запрещено".

InStr.READTEXT(Auda.GetTaskList('Логин','Пароль','Начальная дата','Конечная дата','OPENED'));
Так, тоже ошибку выдает.

Что-то делаю не так...
Старый 06.09.2013, 11:24   #4  
Constantine_imported is offline
Constantine_imported
Участник
 
126 / 10 (1) +
Регистрация: 28.04.2011
Попробуйте как-то так:
Код:
FileName := 'c:\TempAuda.xml';
outfile.TEXTMODE(TRUE);
outfile.CREATE(FileName);
outfile.CREATEOUTSTREAM(outstr);
outstr.WRITETEXT(Auda.GetTaskList('Логин','Пароль','Начальная дата','Конечная дата','OPENED'));
outfile.CLOSE;
Переменные:
Name DataType Subtype Length
FileName Text 250
outfile File
outstr OutStream

P.S. хотя возможно outstr.WRITETEXT тоже не переварит длинную строку и тогда придется читать текст блоками.
Старый 06.09.2013, 12:01   #5  
Albeit is offline
Albeit
Участник
 
9 / 10 (1) +
Регистрация: 06.09.2013
Попробовал
FileName := 'c:\TempAuda.xml';
outfile.TEXTMODE(TRUE);
outfile.CREATE(FileName);
outfile.CREATEOUTSTREAM(outstr);
outstr.WRITETEXT(Auda.GetTaskList('Логин','Пароль','Начальная дата','Конечная дата','OPENED'));
outfile.CLOSE;

Ошибка та же "длина текстовой строки превосходит размер буфера строки".

Нескромный вопрос) как читать текст блоками? понимаю что надо использовать цикл...
Старый 06.09.2013, 12:11   #6  
InTacto is offline
InTacto
Участник
Аватар для InTacto
 
323 / 11 (1) +
Регистрация: 09.08.2005
Лучше вам написать стороннюю библиотечку, которая строку в xml преобразует.
Сделать поток из строки большей 1024 внутренними средствами Нава вряд ли получиться.
Так же есть сомнения по кодировке, что после манипуляций там останется правильный юникод.
Старый 06.09.2013, 13:04   #7  
Constantine_imported is offline
Constantine_imported
Участник
 
126 / 10 (1) +
Регистрация: 28.04.2011
Цитата:
Сообщение от Albeit Посмотреть сообщение
Нескромный вопрос) как читать текст блоками? понимаю что надо использовать цикл...
InTacto по-моему собаку съел на XML'е, так что вероятнее всего он прав. Ваша переменная Auda может вернуть поток? Может у нее какие-то еще методы есть? Если у вас будет входящий поток с данными, его можно будет потом перегнать в исходящий поток и сохранить на диск.
Старый 06.09.2013, 13:24   #8  
Albeit is offline
Albeit
Участник
 
9 / 10 (1) +
Регистрация: 06.09.2013
Библиотека Auda.dll представляет собой COM объект «Auda.Saxif». Для использования
библиотеку необходимо зарегистрировать в системе с помощью regsvr32.exe.
Все методы которые есть:

GetTaskList
Возвращает:
Тип: Строка (Unicode). Xml код, содержащий список запрошенных дел.

GetTaskCalcs
Возвращает:
Тип: Строка (Unicode). Xml код, содержащий список калькуляций по указанному TaskId с
подробной детализацией.

GetVersion
Возвращает:
Тип: Строка (Unicode). Версию используемой библиотеки.

GetFileName
Возвращает:
Тип: Строка (Unicode). Полное имя файла используемой библиотеки.

GetTaskListFilter
Возвращает:
Тип: Строка (Unicode). Xml код, содержащий список запрошенных дел, удовлетворяющих
указанному отбору.

Arguments:

[BSTR GetTaskList :=] Auda.GetTaskList(BSTR login, BSTR password, BSTR datefrom, BSTR dateto, BSTR tab)
[BSTR GetTaskCalcs :=] Auda.GetTaskCalcs(BSTR login, BSTR password, BSTR taskId)
[BSTR GetVersion :=] Auda.GetVersion()
[BSTR GetFileName :=] Auda.GetFileName()
[BSTR GetTaskListFilter :=] Auda.GetTaskListFilter(BSTR login, BSTR password, BSTR filterOnField, BSTR filterValue, BSTR tab)

Два свойства:
debug | [BSTR test :=] Auda.test([BSTR test])
test | [BSTR debug :=] Auda.debug([BSTR debug])
Старый 06.09.2013, 15:36   #9  
rmv is offline
rmv
Участник
 
481 / 11 (1) +
Регистрация: 15.02.2005
Для работы с XML забудьте про writetext b пользуйтесь объектами и методами XML - xmlNode.nodeValue, setAttribute и тп., благо их хватает и для записи и для чтения.
Если уже совсем приспичило и размер значения в узле больше 1024 символов у XMLDOmTextNode есть метод substingData для чтения и appendData для записи.
Этот объект кстати можно использовать для обхода ограничений в 1024 при передачи значений между COM объектами, к примеру вызвать sql запрос любой длины через adoConnection.execute(XMLDOmTextNode.nodeValue).
Старый 06.09.2013, 17:45   #10  
Albeit is offline
Albeit
Участник
 
9 / 10 (1) +
Регистрация: 06.09.2013
Цитата:
Сообщение от rmv Посмотреть сообщение
Если уже совсем приспичило и размер значения в узле больше 1024 символов у XMLDOmTextNode есть метод substingData для чтения и appendData для записи.
Пробовал использовать и эти методы...ошибка та же "длина текстовой строки превосходит размер буфера строки".
Старый 06.09.2013, 22:23   #11  
DA_NEAL is offline
DA_NEAL
Участник
Аватар для DA_NEAL
Лучший по профессии 2017
Лучший по профессии 2009
 
788 / 54 (3) ++++
Регистрация: 05.08.2002
Адрес: Королев
Цитата:
Сообщение от Albeit Посмотреть сообщение
Цитата:
Сообщение от rmv Посмотреть сообщение
Если уже совсем приспичило и размер значения в узле больше 1024 символов у XMLDOmTextNode есть метод substingData для чтения и appendData для записи.
Пробовал использовать и эти методы...ошибка та же "длина текстовой строки превосходит размер буфера строки".
Попробуйте переменные типа BigText.
__________________
Want to believe...
Старый 07.09.2013, 14:51   #12  
InTacto is offline
InTacto
Участник
Аватар для InTacto
 
323 / 11 (1) +
Регистрация: 09.08.2005
BigText тоже не поможет, т.к. опять встает проблема получения потока из полученной строки
Тут нужна уже своя библиотека, через которую можно работать с Auda.dll.

Код на vb6(бибилиотеку с ходу не нашел, так что может быть не вполне рабочий)

Option Explicit

Public Function GetInfAuda(Login_ As String, _
Pass_ As String, _
DateFrom_ As String, _
DateTo_ As String, _
Tab_ As String, _
FileName As String, _
ByRef Errorno As Long, _
ByRef Errortext As String) As Boolean
' FileName - полный путь до файла

Dim vFF As Long, oResp() As Byte
' создаем объект Auda, возможно нужно как то по другому к нему подключаться
Dim Auda1 As Auda
Set Auda1 = New Auda
' Очищаем переменные ошибок
Errorno = 0
Errortext = ""
' запускаем перехват ошибок
On Error GoTo Err
' Получем информацию и помещаем в массив байт
oResp = Auda.GetTaskList(Login_, Pass_, DateFrom_, DateTo_, Tab_)
' создаем файл
vFF = FreeFile
Open FileName For Binary As #vFF
' записываем в файл полученные данные
Put #vFF, , oResp
' сохраняем файл
Close #vFF
' говорим что ф-ция завершилась успешно
SaveWrongFile = True
Exit Function
Err:
' если ошибка, то возвращаем ее номер и описание
Errorno = Err.Number
Errortext = Left(Err.Description, 250)
' говорим что в ф-ции произошла ошибка
SaveWrongFile = False
End Function

К проекту нужно подключить библиотеку Auda
из жирных минусов: необходимость регить 2 библиотеки.
Старый 09.09.2013, 18:24   #13  
Albeit is offline
Albeit
Участник
 
9 / 10 (1) +
Регистрация: 06.09.2013
Спасибо всем за помощь, особенно InTacto!
Задачу решил создав дополнительную Dll

Option Explicit
Public Function SaveGetTaskList(Login_ As String, _
Pass_ As String, _
DateFrom_ As String, _
DateTo_ As String, _
Tab_ As String, _
FileName As String) As Boolean
Dim Auda1 As Auda.Saxif
Dim XmlDoc As MSXML2.DOMDocument
Set XmlDoc = New MSXML2.DOMDocument
Set Auda1 = New Auda.Saxif
XmlDoc.loadXML (Auda1.GetTaskList(Login_, Pass_, DateFrom_, DateTo_, Tab_))
XmlDoc.save (FileName)
End Function


Если делать так:
oResp = Auda.GetTaskList(Login_, Pass_, DateFrom_, DateTo_, Tab_)
' создаем файл
vFF = FreeFile
Open FileName For Binary As #vFF
' записываем в файл полученные данные
Put #vFF, , oResp
' сохраняем файл
Close #vFF

то ломается структура полученного Xml.
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:27.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.