Копирование проекта. Проблема с реестрами, встроенными в карточку редактирования
Добрый день!
У меня в карточке проекта встроено несколько реестров.
Как мне при копировании проекта копировать и эти реестры со всеми данными в них?
Я хотела сделать на dlDataOnDatasetAfterCopy сохранение записи и потом вставку данных в реестры, но у меня в этом событии еще не заполнены другие поля проекта.
1) Где мне лучше сохранить проект? OnShow, может быть?
2) Каким образом я потом пойму, что датасет у меня копирован? И как лучше организовать передачу данных из встроенных реестров в новый проект?
Нравится
Признак копирования - в создаваемое окно при копировании записи передается атрибут 'SourceRecordID' с соответствующим значением. Плюс если не путаю атрибут 'IsCopy'
С встроенными реестрами сложнее... я бы сделал как вариант так - свой обработчик кнопки Копировать, любым способом создаем копию текущей записи с набором нужных реквизитов, к ней крепим нужные записи из встроенных реестров (как продукты в документах, счетах и так далее). Потом поднимаем карточку уже готовой записи на правку, если необходимо.
У меня небольшая проблема возникла. Думаю, что решение простое, просто я не могу найти его :sad:
Копирование встроенных реестром у меня происходит тут:
function dlDataOnDatasetAfterCopy(Dataset, KeyValue) { var TArray = GetData('ds_UserTypes', KeyValue, 'UserTypeID');//сбор записей из встроенного реестра существующего проекта Dataset.Post(); var ProjectID = Dataset('ID'); SetData('ds_UserTypesInProject', ProjectID, TArray, 'UserTypeID');//вставка данных в строенный реестр нового проекта Dataset.Open(); Dataset.Edit(); RefreshDetails();//рефреш детали (в карточке проекта),на которой расположен встроенный реестр }
После этого у меня остается открытой карточка нового проекта, но там не отображаются данные в строенном реестре и при попытке добавить запись в реестр появляется ошибка:
--------------------------- Error --------------------------- Ошибка сохранения записи. Оригинальное сообщение об ошибке: The statement has been terminated. The INSERT statement conflicted with the FOREIGN KEY constraint "FUserTypesInProjectProjectID". The conflict occurred in database "CRM", table "dbo.tbl_Project", column 'ID' --------------------------- OK ---------------------------
Если закрыть карточку нового проекта и открыть заново, тогда все записи на месте и все работает корректно. Мне нужно правильно переоткрыть карточку после записи данных в строенный реестр. Что я не так делаю?
Самое банальное -- попробуйте сделать Post датасета :
Dataset.Post();
после обновления детали.
Ошибка происходит из-за наличия внешнего ключа FUserTypesInProjectProjectID в таблице tbl_UserTypes. Видимо запись данных во встроенный реестр (а именно поля ProjectID) происходит до того, как этот ID попадает в таблицу tbl_Project. Соответственно по проверке целостности происходит ошибка.
Нет, я же перед заполнением встроенного реестра делаю Dataset.Post() и только после этого беру получившийся ProjectID и пишу его в датасет встроенного реестра.
У меня проблема именно в отображении карточки проекта, на ней нет возможности добавить записи в встроенный реестр почему-то. Если переоткрываю карточку, там есть записи в реестрах скопированные.
Была попытка закрыть в скрипте окно проекта (Self.Close()) и затем снова открыть его на редактирование , но ошибка все равно была та же.
Я думала, что RefreshDetail, который использую в коде поможет, но ошиблась.
Может кто-то подсказать, как правильно произвести создание копии и открытие на редактирование записи с встроенными реестрами?
Обратитесь, пожалуйста, в службу поддержки, предоставив все сервисы ветки проектов (как я понимаю детали в карточке ссылаются на стандартные разделы, а не доработанные). Нужно видеть Вашу реализацию.
"Kat" написал:Нет, я же перед заполнением встроенного реестра делаю Dataset.Post() и только после этого беру получившийся ProjectID и пишу его в датасет встроенного реестра.
Вот здесь и проблема. ID в момент копирования датасета также копируется, новый не генерируется. Потому и проблема с внешним ключом. Нужно ID сгенерировать, потом сделать Post, а потом уже и скопировать все детали. К тому же вызовы Open и Edit после Post'а уже ни к чему. Рекомендую переписать Вашу функцию таким образом:
function dlDataOnDatasetAfterCopy(Dataset, KeyValue) { var TArray = GetData('ds_UserTypes', KeyValue, 'UserTypeID');//сбор записей из встроенного реестра существующего проекта var RecordID = Connector.GenGUID(); Dataset.Values('ID') = RecordID; Dataset.Post(); var ProjectID = RecordID; SetData('ds_UserTypesInProject', ProjectID, TArray, 'UserTypeID');//вставка данных в строенный реестр нового проекта RefreshDetails();//рефреш детали (в карточке проекта),на которой расположен встроенный реестр }
в функции CopyRecord есть генерация ID для новой записи, поэтому после копирования выдается ошибка
function CopyRecord(BaseDBEdit, Window){ var Dataset = BaseDBEdit.Dataset; Dataset.DisableGettingDisplayValues(); try { var SourceRecordID = Window.Attributes('SourceRecordID'); try { Dataset.Copy(SourceRecordID);// тут перескакивает в мой обработчик } catch (E){ ShowWarningDialog(E.message); Dataset.Close(); return; } BaseDBEdit.RecordID = Connector.GenGUID(); Dataset.ValAsGUID('ID') = BaseDBEdit.RecordID;//тут вылетает Window.Attributes('RecordID') = BaseDBEdit.RecordID; SetDefaultValues(BaseDBEdit); } finally { Dataset.EnableGettingDisplayValues(); } SetEditWindowCaption(BaseDBEdit, Window); }
В Ваш обработчик перескакивает еще до генерации нового ID, который уже на тот момент Вам нужен для копирования деталей. Поэтому предлагаю генерацию ID в dlDataOnDatasetAfterCopy оставить, а написать проверку в CopyRecord на то, не был ли еще сгенерирован ID : вместо
Dataset.ValAsGUID('ID') = BaseDBEdit.RecordID;
писать
if (IsEmptyGUID(Dataset.ValAsGUID('ID'))) { Dataset.ValAsGUID('ID') = BaseDBEdit.RecordID; }
Виталий, спасибо за совет!
Немного изменила ваш пример кода на:
if (IsEmptyGUID(Dataset.ValAsGUID('ID'))) { BaseDBEdit.RecordID = Connector.GenGUID(); Dataset.ValAsGUID('ID') = BaseDBEdit.RecordID; } else { BaseDBEdit.RecordID = Dataset.ValAsGUID('ID'); }
все работает!
Огромное всем спасибо за помощь!!!!