Вернуться   Андрей Панько. Заметки про Dynamics NAV > Dynamics NAV (Navision)
Справка Пользователи Календарь Поиск Сообщения за день Все разделы прочитаны

Dynamics NAV (Navision) Заметки про Dynamics NAV (ранее Navision) и аддон LS Retail

Ответ
 
Опции темы Поиск в этой теме
  #1  
Старый 15.08.2006, 17:47
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Про датапорт

20.06.06
Правил датапорт. Столкнулся с проблемой: при созданнии на реквест-форме текстбокса, исчезает возможность выбрать файл для импорта.

Для решения надо:
1. Создать глобальную переменную типа текст в 250 символов (например gFileName)
2. Создать на реквест форме текстбокс. Properties: ID = 1, SourceExp = gFileName, AssistEdit = Да.
3. В триггер OnPreDataPort вставить код CurrDataport.FILENAME := gFileName;

Все снова будет работать.
Ответить с цитированием
  #2  
Старый 24.11.2006, 11:21
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Набросал примерчик того, как при выгрузке таблицы товаров в текстовый файл с помощью датапорта, выгрузить дополнительную информацию.

Ситуация. Когда мы работаем с Navision мы легко можем посмотреть кто является поставщиком какого-либо товара. Для это достаточно зайти в карточку товара и посмотреть, что указано в поле Поставщик Но. Если код нам ничего не говорит, с помощью кнопки Look up, расположенной в правой части поля, можно легко попасть в список поставщиков и получить необходимую информацию из него. А теперь представим, что нам нужно выгрузить список товаров (код и наименование) и основных поставщиков (код и наименование) для внешней системы. Как это сделать? Ведь в справочнике товаров указан только код поставщика? Выгружать две таблицы и связывать их в Excel?

Способ есть. Ниже приведена последовательность выполняемых шагов.

1. Создаем датапорт и указываем в нем в качестве dataitem таблицу item (товары, id 27). Находясь на строке, созданного dataitem выберем пункт меню Вид / Dataport Fields и укажем выгружаемые поля: “No.”, “Description”, “Vendor No.”. Т.е. создали датапорт, при запуске которого во внешний файл будут выгружены поля содержащие код товара, наименование товара и код поставщика.

2. Создадим две глобальные переменные:
rVendor, тип Record подтип Vendor.
tVendorName, тип Code длина 30.

3. Находясь на строке, созданного dataitem нажмем F9 И перейдем в редактор C/AL кода. В триггере Item - OnBeforeExportRecord() напишем следующий код:

Код:
IF rVendor.GET(Item."Vendor No.") THEN tVendorName:=rVendor.Name // если поставщик существует, то переменной присваивается его наименование. ELSE tVendorName:=''; //в ином случае переменная очищается.
4. Снова зайдем в Dataport Fields и добавим в него еще одну строку, но на этот раз мы не будем выбирать ее из списка полей таблицы Товары, а вручную укажем имя нашей переменной, содержащей наименование поставщика: tVendorName.

5. Сохраним датапорт.

Во вложенном файле находится уже созданный объект.
Вложения
Тип файла: fob d50000.fob (5.0 Кбайт, 1203 просмотров)
Ответить с цитированием
  #3  
Старый 16.03.2007, 17:21
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Датапортировался. Попутно подтвердил знания.

В том числе о свойстве CallFieldValidate=Да. Действительно срабатывает не всегда. Поэтому кое-где пришлось усилить кодом Validate("Field Name").

При Ctrl+R, записи в таблице не сохраняются. В документации кстати так и написано.
Ответить с цитированием
  #4  
Старый 21.03.2007, 16:04
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
C/SIDE Reference Guide. C/AL Functions. Dataport. 1.

Продолжил начинание.



Датапорт
Датапорты это объекты, используемые для импорта/экспорта данных через внешний текстовый файл.
Для детальной информации о датапортах, смотри руководство Application Designer's Guide.


BREAK (Dataport, Report, XMLport)
Используйте данную функцию для выхода из цикла или из триггера data item датапорта, отчета или XMLпорта.
BREAK
Примечания
При использовании в циклах, например WHILE..DO или REPEAT..UNTIL - BREAK приводит к завершению выполнения цикла, и управление передается операторам, следующим непосредственно за циклом.
Использование BREAK вне цикла приводит к завершению выполнения кода в триггере.
Сравните с функцией QUIT.
Пример
Ниже приведен пример демонстрирующий использование функции BREAK:
Код:
REPEAT Myvar := Myvar +1; IF Myvar = 5 THEN CurrReport.BREAK; MESSAGE(Text000,Myvar); UNTIL Myvar = 10
Создайте следующие текстовые константы в окне C/AL Globals:
Text Constant
ENU Value
Text000
'Myvar сейчас равно %1'
При выполнении данного кода, цикл будет прерван когда значение MyVar станет 5.


DATAPORT.RUN (Dataport)
Данная функция используется для загрузки и выполнения определенного датапорта. Если на этапе разработки, неизвестно какой датапорт потребуется запустить используется данная функция или функция DATAPORT.RUNMODAL. Если требуется запускать конкретный датапорт, следует использовать функции RUN (Dataport) или RUNMODAL (Dataport).
DATAPORT.RUN(Number [, ReqWindow] [, Record])
Number
Тип данных: integer
Идентификатор (ID) датапорта, который требуется выполнить. Можно использовать C/AL Symbol меню, для выбора из списка.
Если указанный датапорт не существует, будет вызвана ошибка выполнения (run-time error).
ReqWindow
Тип данных: boolean
Указывает системе о необходимости отображения формы запроса. Форма запроса является частью датапорта.
Цитата:
Чтобы…Укажите…
Отобразить форму запроса перед выполнением датапорта TRUE (по умолчанию)
Выполнить датапорт без отображения формы запроса FALSE
Record
Тип данных: record
Указывает системе, запись которая будет передана в датапорт. Таким образом в датапорт передаются фильтры.


DATAPORT.RUNMODAL (Dataport)
Данная функция используется для загрузки и выполнения определенного датапорта. Если на этапе разработки, неизвестно какой датапорт потребуется запустить используется данная функция или функция DATAPORT.RUN. Если требуется запускать конкретный датапорт, следует использовать функции RUN (Dataport) или RUNMODAL (Dataport).
DATAPORT.RUNMODAL(Number [, ReqWindow] [, Record])
Number
Тип данных: integer
Идентификатор (ID) датапорта, который требуется выполнить. Можно использовать C/AL Symbol меню, для выбора из списка.
Если указанный датапорт не существует, будет вызвана ошибка выполнения (run-time error).
ReqWindow
Тип данных: boolean
Указывает системе о необходимости отображения формы запроса. Форма запроса является частью датапорта.
Чтобы…Укажите…
Отобразить форму запроса перед выполнением датапорта TRUE (по умолчанию)
Выполнить датапорт без отображения формы запроса FALSE
Record
Тип данных: record
Указывает системе, запись которая будет передана в датапорт. Таким образом в датапорт передаются фильтры.
Примечания
Форма запроса запускается в модальном режиме.


FILENAME (Dataport)
Данная функция используется для установки нового значения в свойство FileName датапорта, а также возвращает текущее значение указанного свойства.
[CurrFileName] := FILENAME([NewFileName])
CurrFileName
Тип данных: text
Текущее значение свойства FileName.
NewFileName
Тип данных: text
Новое значение свойства FileName.
Примечания
Смотри описание свойства FileName для дополнительной информации.


IMPORT (Dataport)
Данная функция используется для установки нового значения в свойство Import датапорта, а также возвращает текущее значение указанного свойства.
[IsImport] := IMPORT([SetImport])
IsImport
Тип данных: boolean
Текущее значение свойства Import.
SetImport
Тип данных: boolean
Новое значение свойства Import.
Примечания
Смотри описание свойства Import для дополнительной информации.
Ответить с цитированием
  #5  
Старый 21.03.2007, 16:05
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
C/SIDE Reference Guide. C/AL Functions. Dataport. 2.

QUIT (Dataport, Report, XMLport)
Используйте данную функцию, чтобы прервать выполнение датапорта, отчета или XMLпорта.
QUIT
Примечания
При вызове функции QUIT работа датапорта, отчета или XMLпорта прерывается, а сделанные изменения в базе данных откатываются. Функция не может быть вызвана из триггеров OnPostReport, OnPostDataPort или OnPostXMLport.


RUN (Dataport)
Данная функция используется для загрузки и выполнения определенного датапорта. Данная функция или функция RUNMODAL (Dataport) используется, если на этапе дизайна известно, какой датапорт потребуется запускать. В противном случае используются функции DATAPORT.RUNMODAL или DATAPORT.RUN .
Dataport.RUN
Dataport
Тип данных: dataport
После того как была определена данная переменная, данная функция или функция RUNMODAL этой переменной может использоваться. Система автоматически очищает переменную после выполнения функции.


RUNMODAL (Dataport)
Данная функция используется для загрузки и выполнения определенного датапорта. Данная функция или функция RUN (Dataport) используется, если на этапе дизайна известно, какой датапорт потребуется запускать. В противном случае используются функции DATAPORT.RUNMODAL или DATAPORT.RUN .
Dataport.RUNMODAL
Dataport
Тип данных: dataport
После того как была определена данная переменная, данная функция или функция RUN этой переменной может использоваться. В противоположность функции RUN, система не очищает переменную после выполнения функции. Очищать переменную после использования нужно вручную.
Примечания
Форма запроса запускается в модальном режиме.


SETTABLEVIEW (Dataport Form & Report)
On Error Resume Next Document.Write CompanyNotes(Window.Location.Pathname) Данная функция используется чтобы применить Table View указанной записи к table view формы, отчета или датапорта.
SETTABLEVIEW(Record)
Record
Тип данных: record
Запись, с которой будет скопировано table view (фильтры, ключи и направления сортировки) и применено к форме или data item.
Примечание
Данная функция только сузит table view предварительно заданный в свойствах SourceTableView формы или DataItemTableView data item.
Если используется данная функция, система не сохранит текущий table view в файле настроек, даже если в свойстве SaveTableView формы установлено значение «Да».


SKIP (Dataport, Report, XMLport)
Используйте данную функцию, чтобы прервать текущую итерацию датапорта, отчета или XMLпорта.
SKIP
Примечания
Чтобы пресечь вывод на экран секции отчета можно использовать SHOWOUTPUT , функция, SKIP позволяет запретить любые действия (а не только вывод на экран) и продолжить выполнение датапорта, отчета или XMLпорта.
Пример
Если в триггере OnAfterGetRecord выполняются какие-либо действия, и эти действия при некоторых ситуация выполняться не должны, следует использовать функцию SKIP следующим образом:
Код:
IF Balance = 0 THEN CurrReport.SKIP ELSE ... // требуетмые действия
Типичная ситуация использования SKIP, это получение записей из связанной таблицы, используя значения текущей записи в качестве фильтра. Если на основании значений в текущей записи очевидно, отсутствие записей в подчиненной таблице и нет необходимости выполнять указанные действия используется SKIP.
Ответить с цитированием
  #6  
Старый 03.05.2007, 09:20
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
чаво про датапорты

Имя файла.

1. Имя файла можно указать на закладке Параметры.
2. Имя файла может задаваться в свойстве Filename. В этом случае на закладке Параметры поле выбора файла отсутствует.
3. Имя файла можно присваивать программно, используя функцию CurrDataport.FILENAME
4. Если пользователь должен указать только каталог то удобно применять следующее знание http://forum.mazzy.ru/index.php?showtopic=3554.
5. Если на закладке параметры добавить свои реквизиты, то стандартное поле выбора файла исчезнет, чтобы его вернуть нужно:
I. Создать глобальную переменную типа текст в 250 символов (например gFileName)
II. Создать на реквест форме текстбокс. Properties: ID = 1, SourceExp = gFileName, AssistEdit = Да.
II. В триггер OnPreDataPort вставить код CurrDataport.FILENAME := gFileName;

Фичи
1. Иногда требуется выгрузить в файл некоторую константу, причем такого поля в таблице нет. Для этого можно воспользоваться переменными подробнее http://www.apanko.ru/showpost.php?p=168&postcount=2.
2. Если с помощью датапорта организуется логирование каких либо событий, т.е. датапорт должен выполнял запись в конец файла, а не переписывал его. Как это организовать смотри http://forum.mazzy.ru/index.php?showtopic=1958.
3. Использование датапорта для выгрузки/загрузки между разными таблицами. Создать два датаайтема, с одинаковой структурой выгружаемых/загружаемых полей (если полей не хватает – использовать переменные). В триггере onPreDataItemданных датайтемов написать:
IFCurrDataport.IMPORT THEN CurrDataport.BREAK;// для выгружаемой таблицы
или
IF NOT CurrDataport.IMPORT THEN CurrDataport.BREAK;// длязагружаемойтаблицы
4. Подготовка файлов для загрузки (формат “field 1”;”field 2”).
Лучше всего использовать MS Excel. Формат сохраняемого файла: CSV (MS-DOS) (*.csv)
5. Просмотр выгружаемых файлов(формат “”;””). Выгруженный файл лучше всего открывать с помощью MS Excel. Файл / Открыть, выбрать текстовый файл. Откроется окно Мастер текстов (импорт). На первой закладке указать Формат данных = С разделителями, Формат файла = 866:Cyrillic (DOS). На второй закладке указать Символ-разделитель = «;». При необходимости на третьей закладке указать форматы столбцов.
6. Тестирование датапорта. Если находясь в дизайнере запустить датапорт с помощью При Ctrl+R, импортированные записи в таблице не сохранятся.

Проблемы
1. Проблема при загрузке полей длиной более 70 символов. Решение проблемы смотри здесь http://www.axforum.info/forums/showthread.php?t=3472.
2. Не смотря на параметр CallFieldValidate = Yes, триггер onValidate срабатывает не всегда вместо этого стоит использовать код ValidateFieldName»).

Литература
1. http://www.microsoft.com/Rus/Download.aspx?file=/dynamics/nav/navision_objects.pdf (рус. Navision Objects)
2. http://www.geocities.com/navision_attain/downloads.html (англ. Navision Development, Intro to C/AL Programming)
3. http://emiel.romein.googlepages.com/w1w1adg.pdf (англ. Navision Application Designers Guide)

Ответить с цитированием
  #7  
Старый 16.04.2008, 17:42
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Граждане сталкиваются с проблемой - какой выбрать символ для разделителя:
" - нельзя использовать текст в ковычках
$ - так сумму отката в долларах не выгрузишь
@ - проблема с выгрузкой адресов электронной почты.

Лично я, в сложных случаях применяю несколько символом идущих подряд.

FieldStartDelimiter = [[[[
FieldEndDelimiter = ]]]]
FieldSeparator =####
Ответить с цитированием
  #8  
Старый 17.04.2008, 12:37
Kalex
 
Сообщения: n/a
Я обычно использую редко встречающийся знак "|". По моему использование несколько одинаковых знаков (@@@, [[[ и т.д.) не есть хорошо, т.к. в случае пустых значений могут быть глюки. Можно попробовать в качестве разделителя использовать табуляцию - <Tab>.

Кстати, спасибо за форум - много интересного.
Ответить с цитированием
  #9  
Старый 26.04.2008, 15:33
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Давече на известном форме был задан вопрос "как выгрузить данные в заданном формате?"
Цитата:

В общем целом нужно сделать что-то вроде этого:
Цитата:

Документ=Платежное поручение
СекцияДокумент=Платежное поручение
Номер=1
Дата=01.01.2008
Сумма=xxx
...
НазначениеПлатежа2=xxx
НазначениеПлатежа3=xxx
КонецДокумента
КонецФайла
Вместо иксов, соответственно, данные

Коллеге подсказали как решить эту задачу.
Попробуем тоже самое сделать датапортом.

1. Создадим датапорт со следующими свойствами:
  • Import = No (т.к. задача изначально про выгрузку, про импорт речь не шла, значит импорт будем делать за отельные деньги).
  • FileFormat = Variable
  • FieldStartDelimiter и FieldEndDelimiter = <None> (спец. код, означает, что никаких символов для ограничения полей использовать не нужно)
  • FieldSeparator = <NewLine> (да, мы позаимстовали идею у Fordewind)
  • RecordSeparator = <NewLine><NewLine> (хотя тут возможны варианты).
2. Создадим датаайтем со следующими свойствами:
  • DataItemTable = Item (для эксперимента сойдет любой)
  • DataItemTableView - на свое усмотрение.
3. Для датаайтема определим следующие DataPort Fields: "No." и Description.

Теперь если запустить датапорт, то получим:
Цитата:
1000
‚Ґ«®бЁЇҐ

1001
’гаЁбвЁзҐбЄЁ© ‚Ґ«®бЁЇҐ

1100
ЏҐаҐ¤&shy;ҐҐ Є®«Ґб®

Теперь переведем это на русский и добавим в начале каждой строки название поля. Для этого в триггерах onAfterFormatField напишем следующий код:
Код:
Text:=COPYSTR(cLocal.Dos2Win(Item.FIELDCAPTION("No.")+': '+Text),1,1024); //cLocal - это кодеюнит 12400 Localisation Management.
Вместо Item.FIELDCAPTION("No.")+': ' можно написать, что угодно, например 'Код товара: '. Теперь результат будет выглядеть следующим образом:
Цитата:
Но.= 1000
Описание= Велосипед

Но.= 1001
Описание= Туристический Велосипед

Но.= 1100
Описание= Переднее колесо

Уже почти похоже. Осталось добавить "КонецДокумента" и "КонецФайла".

Для этого накодим в следующих триггерах:
Код:
Dataport - OnInitDataport() //переменные типа char (вместе 13 и 10 служат признаком конца строки) ch10:=10; ch13:=13; Dataport - OnPostDataport() CurrFile.WRITE(ch13); CurrFile.WRITE(ch10); CurrFile.WRITE(cLocal.Dos2Win('КонецДокумента')); Item - OnAfterExportRecord() CurrFile.WRITE(ch13); CurrFile.WRITE(ch10); CurrFile.WRITE(cLocal.Dos2Win('Конец Записи'));

Теперь результат:
Цитата:

Но.= 1000
Описание= Велосипед
Конец Записи

Но.= 1001
Описание= Туристический Велосипед
Конец Записи

Но.= 1100
Описание= Переднее колесо
Конец Записи
Конец Документа

Задача решена.
Ответить с цитированием
  #10  
Старый 22.05.2008, 19:08
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Вставка многих полей.

Так давно не пользовался датапортами, что и забыл.
Помню, что очень мучался создавая датапорт на большую таблицу.

Оказалось, что в Field Designer работает Field Menu.

Т.е. действуем так:
  1. создаем DataItem (например Item, таблица 27).
  2. переходим в режим Field Designer
  3. нажимаем кнопку Field Menu
  4. выбираем нужные поля (все или через ctrl)
  5. щелкаем мышью в поле SourceExpr (или любом другом)
  6. на вопрос "Do you want to append the fields that are selected in the field menu?" отвечаем Да.
Ответить с цитированием
  #11  
Старый 18.06.2008, 16:31
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Интересную штуку сообщили здесь: http://forum.mazzy.ru/index.php?showtopic=11475&hl=

Смысл в том, что в SourceExpr окна Dataport Fields кроме непосредственно полей обрабатываемой таблицы, а также переменных, можно указывать код C/AL.

Автору - почет и уважение.
Ответить с цитированием
  #12  
Старый 31.10.2008, 11:19
apanko apanko вне форума
Администратор
 
Регистрация: 15.08.2006
Сообщения: 1,629
Обсуждали как при импорте данных из датапорта, не обнулять значения в таблице.

Можно установить свойства DataItem:
* AutoUpdate = Yes
* AutoReplace = No

Но они работают если в таблицу импортуются не все поля. Т.е. в справочник товаров импортируются только цены (в датапорте два поля Товар Но. и Цена). В этом случае датапорт обновит в таблице только поле Цена, а остальные поля не тронет.

Если же поле есть в датапорте, но оно пустое то тут ситуация сложнее.

Мое решение. Возможно есть и другие.
Объявляем такую же переменную Record как и импортируемая таблица (например, 27 - товары).
Объявляем переменную такого же типа как поле первичного ключа этой табицы (считаем, что в первичный ключ входит одно поле). Например cNo code 20.
И еще одну переменную типа Boolean (bExist)
В триггере OnBeforeEvaluateField(VAR Text : Text[1024]) поля первичного ключа (в нашем случае "Но.") пишем такой код:
Код:
//EVALUATE(cNo,Text); //это если поле типа integer, для code думаю хватит: cNo:=Text; //тут надо смотреть, что передается в переменной Text, возможно придется отрезать пробелы (т.к. длина явно не совпадает). Не проверял, но заставить работать не сложно. IF rItem.GET(cNo) THEN bExist:=TRUE;

Далее в триггере OnAfterImportRecord()датаайтема пишем
Код:
IF bExist THEN IF (Поле1='')AND(rItem.Поле1<>'') THEN Поле1:=rItem.Поле1; //или Валидейт, что больше нравится. .... MODIFY; END;
Ответить с цитированием
Ответ


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

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 19:51.

Контакты: e-mail, телефон: +7(926)1805967 - Архив - Вверх

Microsoft Most Valuable Professional
vBulletin v3.5.4, Copyright ©2000-2019, Jelsoft Enterprises Ltd.
Русский перевод: zCarot, Vovan & Co
Права на все материалы, опубликованные на блогофоруме принадлежат Андрею Панько, если в самом материале не указано иное.
Рейтинг@Mail.ru Rambler's Top100