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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.07.2011, 12:31   #1  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Уважаемые коллеги, в очередной раз обращаюсь к вам за помощью Подскажите, плиз, как оптимальнее сдалать следующее:
нужно просмотреть все таблицы, и проверить в этих таблицах содержимое полей с типом Code на предмет присутствия в них запрещенных символов (например ß или œ) и заменить их на "правильные" (ss и ü соответственно). Обработку я написала. Ее можно запускать в двух режимах: либо только проверка с заполнением протокола, либо проверка с исправлением (новое значение в поле заношу с помощью команд:
Код:
Fld_ref.VALIDATE(NewValue);
Tbl_ref.MODIFY;
Первый режим работает без проблем. А со вторым возникают следующие заморочки:
а) Не во всякой таблице мне можно корректировать значения (например, при исправлении в Т112 пишет: "У вас нет прав на изменения в записях таблицы Sales Invoice Header")
б) Некоторые Code-поля содержат TableRelation. И их исправление тоже вызывает ошибку: ругается что-то типа "в таблице такой-то (называется исходная таблица, на которую ссылается поле) нет такого NewValue значения)
Проблема понятна и в принцепе все логично. Но дело в том, что и старое-то значение тоже отсутствует в исходной таблице (предполагаю, что оно туда затесалось еще со времен доисторических, когда базу конвертировали из одной версии Нава в другую).
Вопрос понятен:
1) как быть и что делать? как обойти эти "углы" (править ручками ну ооочень не хочется, т.к. полей с ошибками довольно много .... если помножить это еще и на порядка 10 мандантов, у каждого из которых неск. сот (а то и млн) записей в основных таблицах)

Попутно еще парочка вопросов:

2) Есть ли такая команда в Наве, к помощью которой можно было бы "сделать примерку", т.е. фактически не заносить новое значение в поле, а лишь примерить "придется ли оно по вкусу системе". При отрицательном ответе я бы выводила некое сообщение в протокол проверки: дескать такое-то поле в такой-то записи исправить автоматически низя.

3) Как выявить поля, имеющие TableRelation (чтобы сообщение о таковых тоже было напечатано в протоколе)?
В своей обработке я пользуюсь таблицей 2000000041 Fields. В ней есть поля RelationTableNo и RelationFieldNo. Я наивно полагала, что если RelationTableNo > 0, то это указывает на то, что поле содержит ссылку на др. таблицу. Но оказалось, что это не всегда так (выражаясь языком математическим: это достаточное условие, но не необходимое)
Пример: таблица 110 (Sales Shipment Header) - поле Sell-to Customer No содержит ссылку на таблицу 18 (Customer) (свойство TableRelation = Customer). RelationTableNo для него = 18
та же таблица - поле Ship-to Code: В свойстве TableRelation написано: "Ship-to Address".Code WHERE (Customer No.=FIELD(Sell-to Customer No.)).
Но в то же время RelationTableNo = RelationFieldNo = 0.

4) И вообще правильно ли я использую Fld_ref.VALIDATE для присваивания нового значения полю? Может "лучше" было бы обычным присваиванием (без валидации) ?

5) Какие еще подводные камни могут тут встретиться?

6) Обработка последовательно выбирает все таблицы БД, проверяет, исправляет. Если таблица Х проверена и исправлена благополучно, а на таблице Х+1 обработка "спотыкнулась" и прервалась сообщением об ошибке, то и изменения в таблице Х сохранены не будут. Разумно ли использовать COMMIT, чтобы хотя бы изменения в первой таблице сохранить? И на сколько скажется такая принудительная запись на времени выполнения процедуры?
Старый 27.07.2011, 13:23   #2  
Sancho is offline
Sancho
Administrator
Аватар для Sancho
Лучший по профессии 2017
Лучший по профессии 2009
 
1,294 / 221 (10) ++++++
Регистрация: 11.01.2006
начинать надо со справочников: Customer, Shipping Agent и пр.
причем делать это не через VALIDATE, а через RENAME. в этом случае все связанные записи по тейбл релейшн сами обновятся.
справочник обработали - COMMIT

чтобы не "спотыкаться" на ошибках, можно использовать такие конструкции как IF Recordref.MODIFY THEN;
Старый 27.07.2011, 14:39   #3  
Alterant is offline
Alterant
Участник
 
378 / 10 (1) +
Регистрация: 31.03.2004
Цитата:
Сообщение от Sancho Посмотреть сообщение
чтобы не "спотыкаться" на ошибках, можно использовать такие конструкции как IF Recordref.MODIFY THEN;
И еще простое присвоение вместо validate. MODIFY вряд ли в данном случае будет проблемой, хотя и не помещает обернуть его в IF.
Старый 27.07.2011, 23:07   #4  
alexb_imported is offline
alexb_imported
Участник
 
256 / 12 (1) ++
Регистрация: 25.08.2006
1. По-поводу присвоения значений:
то, что НАВ ругается при присвоении значения через VALIDATE, то это от того, что поле имеет RELATION к другой таблице и ругань исходит от свойства ValidateTableRelation=<Yes>. Поэтому в любом случае надо делать простым присвоением. НО:
Разбейте Вашу обработку на два этапа.
- В первом этапе присвойте новое значение ТОЛьКО тем полям, которые входят в первичный ключ, через RENAME (Sancho абсолютно прав) . Сам процесс из-за этого несколько затянется, но это наиболее "чистый" вариант. Чтобы узнать, входит ли поле в первичный ключ: для этого используйте таблицу "Key" и переменную типа "KeyRef". После каждого RENAME сделать COMMIT.
- Во втором этапе пройдитесь по остальным "простым полям", которые не входят в первичный ключ. Посредством RENAME в первом этапе изменения в таблице А автоматом занеслись в другие таблицы (B, C D...) которые имеют TableRelation к таблице А, так что колличество таблиц/полей, где надо присвоить новое значение, автоматом уменьшилось (НАВ уже сделал часть работы за Вас). В этих "простых полях", которые не входят в первичный ключ, присвойте новое значение без VALIDATE.

2. По-поводу "У вас нет прав на изменения в записях таблицы Sales Invoice Header": добавьте в propertys обьектa, где выполняется обработка (наверное Codeunit или Report) Permissions для таблицы Sales Invoice Header и других таблиц, по мере появления такой ошибки и для других таблиц.
И по-моему правильнее будет делать изменения "нормальным" MODIFY, без IF, а то так и не узнаете, где и почему не удалось присвоить новое значение.
Старый 11.08.2011, 16:34   #5  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от AlexB Посмотреть сообщение
1. По-поводу присвоения значений:
то, что НАВ ругается при присвоении значения через VALIDATE, то это от того, что поле имеет RELATION к другой таблице и ругань исходит от свойства ValidateTableRelation=<Yes>. Поэтому в любом случае надо делать простым присвоением. НО:
Разбейте Вашу обработку на два этапа.
- В первом этапе присвойте новое значение ТОЛьКО тем полям, которые входят в первичный ключ, через RENAME (Sancho абсолютно прав) . Сам процесс из-за этого несколько затянется, но это наиболее "чистый" вариант. Чтобы узнать, входит ли поле в первичный ключ: для этого используйте таблицу "Key" и переменную типа "KeyRef". После каждого RENAME сделать COMMIT.
- Во втором этапе пройдитесь по остальным "простым полям", которые не входят в первичный ключ. Посредством RENAME в первом этапе изменения в таблице А автоматом занеслись в другие таблицы (B, C D...) которые имеют TableRelation к таблице А, так что колличество таблиц/полей, где надо присвоить новое значение, автоматом уменьшилось (НАВ уже сделал часть работы за Вас). В этих "простых полях", которые не входят в первичный ключ, присвойте новое значение без VALIDATE.

2. По-поводу "У вас нет прав на изменения в записях таблицы Sales Invoice Header": добавьте в propertys обьектa, где выполняется обработка (наверное Codeunit или Report) Permissions для таблицы Sales Invoice Header и других таблиц, по мере появления такой ошибки и для других таблиц.
И по-моему правильнее будет делать изменения "нормальным" MODIFY, без IF, а то так и не узнаете, где и почему не удалось присвоить новое значение.
Ребята, всем спасибо за подсказки! (За неимением смайлика с цветочком пусть будет такой: )

По ходу еще вопросы: у меня есть две переменные: типа Recordref и типа Fieldref. Каким боком к ним можно Rename применить?

Я правильно думаю: простое присваивание доолжно выполняться через команду: Fld_ref.VALUE(NewVal) ?
Старый 11.08.2011, 16:43   #6  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от AlexB Посмотреть сообщение
2. По-поводу "У вас нет прав на изменения в записях таблицы Sales Invoice Header": добавьте в propertys обьектa, где выполняется обработка (наверное Codeunit или Report) Permissions для таблицы Sales Invoice Header и других таблиц, по мере появления такой ошибки и для других таблиц.
И по-моему правильнее будет делать изменения "нормальным" MODIFY, без IF, а то так и не узнаете, где и почему не удалось присвоить новое значение.
Этот вариант не прокатывает. Как только я прописываю в Permission нужные мне таблицы (а это такие таблицы как 17, 110-113 и т.п.) и пытаюсь сохранить форму, он ругается, что у меня нет прав вносить изменения в эти таблицы. Полагаю это происходит из-за нашей "неполной" лицензии.

Но эта "беда" меня беспокоит меньше всего, т.к. для внесения изменений в эти таблицы мы можем воспользоваться лицензией фирмы-партнера.
Старый 11.08.2011, 20:48   #7  
alexb_imported is offline
alexb_imported
Участник
 
256 / 12 (1) ++
Регистрация: 25.08.2006
Цитата:
Сообщение от Kadawrik Посмотреть сообщение
По ходу еще вопросы: у меня есть две переменные: типа Recordref и типа Fieldref. Каким боком к ним можно Rename применить?
Я правильно думаю: простое присваивание доолжно выполняться через команду: Fld_ref.VALUE(NewVal) ?
1.Recref.RENAME(new values для перв. ключей разделённых через запятую); т.е RENAME производится таким же макаром как и обычной Rec-Variable
2.простое присвоение, как вы и правльно подумали, Fieldref.Value("new value").
Старый 14.09.2011, 18:41   #8  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Ребята, спасибо всем большое. (где тут смайлик с цветочком?)

Еще один вопрос на другую тему (сорри, торможу че-та седня совсем):
требуется открыть форму списка с заданным порядком сортировки, только не по возрастанию, а по убыванию.
Использую команду SETCURRENTKEY("Поле 1")
а как указать, что по убыванию надо?
Старый 14.09.2011, 18:51   #9  
Sancho is offline
Sancho
Administrator
Аватар для Sancho
Лучший по профессии 2017
Лучший по профессии 2009
 
1,294 / 221 (10) ++++++
Регистрация: 11.01.2006
ASCENDING(FALSE)
Старый 15.09.2011, 10:22   #10  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от Sancho Посмотреть сообщение
ASCENDING(FALSE)
Danke
 


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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 00:49.