Как можно создать объект с именем удаленного ранее (при этом удалена таблица из базы данных)? Сейчас при публикации такого объекта Oracle ругается что таблица не найдена или ее нет, но ее и правда нет же, ORM по идее должно же ее создать?
Если объект был удалён и из конфигурации, и из базы полностью, не оставив никаких следов, то разницы с изначальным отсутствием быть не должно.
Сначала убедитесь, точно ли на ту таблицу ругается, может, совсем и на другую. Если установлено on site, можно отловить запросы в базу. И посмотрите на полный стек сообщения при ошибке.
На уровне базы. Слишком мало конкретики о том, какой объект был, как удаляли, что на него осталось завязано и какая возникает ошибка после каких SQL-запросов.
Подскажите, как можно осуществить проверку наличия таблиц и их колонок БД по именам, используя EntitySchemaManager в веб-сервисе? Чтобы проверить перед внесением изменений в БД.
Добрый день. Как реализовать кликабельную таблицу в BPM? Тобишь, в контейнер нужно выводить таблицу N*N, по клику на ячейку: получать ее индекс в таблице, данные из нее, перерисовывать таблицу. Для того что бы это реализовать нужно описывать новую модель представления? Или уже есть "что-то" базовое, описанное, что можно использовать как основу?
В случае если Вы столкнулись с проблемой анализа объема таблицы в базе SQL, а так же Вам нужно узнать, сколько в ней записей и какой объём занимают индексы, - Вам необходимо выполнить скрипт из вложения и проанализировать результат в полученной таблице.
для того, чтобы проходится не по всему множеству записей, можно установить PageRowsCount, например, в 1000. Тогда будут браться первые 1000 записей реестра (по аналогии с SQL - Top 1000).
для того, чтобы проходится не по всему множеству записей, можно установить PageRowsCount, например, в 1000. Тогда будут браться первые 1000 записей реестра (по аналогии с SQL - Top 1000).
задача - в реестре контрагентов отфильтровать контрагентов, например по городу и исключая конкурентов, после чего нажать на кнопку "Отправить КП" и в таблицу отправки КП заносятся все записи являющиеся результатом выборки
например, в городе Н 10000 компаний, всем надо выбрать в реестре и нажать кнопку отправить всем КП
как мне кажется, Вам лучше реализовать этот функционал через действие, которое будет запускать бизнес-процесс.
Передавать в него массив можно следующим образом.
Можно переопределить обработчик события StartRunModuleProcess и скопировать в скрипт код из базового метода, но сделать проверку, чтобы коллекция контрагентов выбиралась только для Вашего процесса.
if(schema.Parameters.ExistsByName("TreeGridSelectedRowsIds")){if(schema.Name=='название Вашего процесса'{// здесь Ваш запрос на выборку необходимых контрагентов с помощью EntitySchemaQuery// .......
propValue[i]= idsCollection[i];
moduleProcess.SetPropertyValue("TreeGridSelectedRowsIds", propValue);}else{
var idsCollection = dataSource.SelectedItemPrimaryColumnValues;
var selectedRowsCount = idsCollection.Count;
var propValue =new Guid[selectedRowsCount];for(var i =0; i < selectedRowsCount; i++)
propValue[i]= idsCollection[i];
moduleProcess.SetPropertyValue("TreeGridSelectedRowsIds", propValue);}}
В процессе администрирования базы данных возникла необходимость определить причину возникновения ошибки. Определенный объём информации импортируется в базу данных, с которым далее пользователи работают. В процессе заполнения определенного набора полей автоматически высчитывалась итоговая сумма в поле «Итого». Но в определённый промежуток времени использования продукта начали появляться ошибки, связанные с несоответствием значения поля «Итого» сумме полей из которых оно вычисляется («Сумма покупки», «Наценка», «Сбор» и т.д.). Так как ошибку не получалось явно повторить, необходимо было разработать механизм для решения данной проблемы.
Естественно самой реальной и первой причиной возникновения такой ошибки приходила идея о сбоях в работе событий полей окна редактирования (то есть значения в полях изменялись, а события данных полей(-я) не срабатывали).
В основу решения было положено создание двух таблиц в базе данных для ведения логов, что происходят с записью набора данных. Первая таблица WindowLog, а вторая TriggerLog.
Первая таблица WindowLog включает в себя поля «Дата создания»(CreatedOn), «Идентификатор записи» (RecordID), «Ответственный» (WindowsUser), «Имя поля породившего событие»(FieldName), «Итого» и поля из которых оно вычисляется («Сумма покупки», «Наценка», «Сбор» и т.д.). Для наполнения таблицы было использованы события невизуального компонента окна dlData: dlDataOnDatasetDataChange, dlDataOnDatasetBeforePost и dlDataOnDatasetAfterPost. В скрипте в событиях была создана функция, которая формировала SQL запрос к таблице WindowLog базы данных с фиксацией информации по указанным полям на момент срабатывания события.
Вторая таблица TriggerLog включает в себя поля «Дата создания»(CreatedOn), «Идентификатор записи» (RecordID), «Состояние» (до изменения записи и после), «SystemUser», «Итого» и поля из которых оно вычисляется («Сумма покупки», «Наценка», «Сбор» и т.д.). Для заполнения данной таблицы был создан триггер на инструкцию UPDATE проблемной таблицы с двумя запросами вставки значений в таблицу. В одном запросе вставлялись значения до изменений, а во втором после.
Запрос №1:
INSERTINTO TriggerLog (*набор полей*) SELECT(*набор полей*) FROM deleted
Запрос №2:
INSERTINTO TriggerLog (*набор полей*) SELECT(*набор полей*) FROM inserted
Результатом использования данного решения на основе анализа таблицы WindowLog было установлено, что срабатывают все события окна редактирования, влияющие на вычисление значения поля «Итого». В процессе использования окна редактирования и после сохранения записи значения поля «Итого» были корректны.
Проанализировав записи в таблице TriggerLog было установлено, что в результате выполнения инструкции UPDATE было внесено некорректное значение. Сопоставив даты создания записей в таблице TriggerLog и WindowLog было установлено, что инструкция UPDATE была вызвана не в результате манипуляций с окном редактирования, а иным источником. На основании поля «SystemUser» таблицы TriggerLog было установлено что изменения были внесены с помощью импортера данных.
Таблицу TriggerLog возможно расширить, добавив в нее поля, которые помогут ускорить процесс обнаружение источника изменений записи базы данных. Список дополнительных полей может выгладять следующим образом: ApplicationName, LoginName, HostName.
PS: Принимаю предложения на доработку вашей конфигурации!!! Для более детальной информации можно связаться по следующему e-mail адресу: providnui@ukr.net !!!
В случае возникновения дополнительных вопрос по теме могу поделиться более детальной информацией.
Не у всех датасетах есть дата создания. а мне нужно получить дату, что бы проверить меньше ли она текущей. И после чего сделать условие. Это функция из скрипта.
В dataset можно "вытащить" эту дату и получать ее с помощью функции GetDatasetFieldValueByID либо GetDatasetFieldValueFromDatasetByUSI, обе функции находятся в скрипте scr_DB.
Добрый день! У меня следующая проблема. Мне нужно скриптом обновить поля "Вид деятельности" и "Отрасль" контрагента. Делаю Следуюшим образом:
function UpdateAccount(AccountID, ActivityName, FieldName){ var AccountDS = Services.GetNewItemByUSI('ds_Account');// или //GetSingleItemByCode('ds_Account', 'ContactIntegration');
ApplyDatasetIDFilter(AccountDS, AccountID,true);
AccountDS.Open(); var NewActivityID = GetAccountActivityID(ActivityName); var NewFieldID = GetAccountFieldID(FieldName);
AccountDS.Edit(); if(AccountDS('ActivityID')!= NewActivityID){ var Message = FormatStr(ConfirmActivityChangeMessage, AccountDS.ValAsStr('ActivityName'), ActivityName, AccountDS('Name')); if(ShowConfirmationDialog(Message)== wmrYes){
AccountDS('ActivityID')= NewActivityID; } } if(AccountDS('FieldID')!= NewFieldID){ var Message = FormatStr(ConfirmFieldChangeMessage, AccountDS.ValAsStr('FieldName'), FieldName, AccountDS('Name')); if(ShowConfirmationDialog(Message)== wmrYes){
AccountDS('FieldID')= NewFieldID; } }
AccountDS.Post();
AccountDS.Close(); }
На строке AccountDS.Post() У меня следующая ошибка: Ошибка сохранения записи. Оригинальное сообщение об ошибке: The statement has been terminated.
Cannot insert the value NULL into column 'Name', table 'CRM.dbo.tbl_Account'; column does not allow nulls. UPDATE fails.
Посмотрел в профайлере, и, действительно, на сервер посылается запрос на обновление почему то всех полей таблици tbl_Account, а параметры заданы только двух полей, это FieldID и ActivityID.
Михаил, у Вас переменная AccountID содержит значение? После открытия датасет AccountDS содержит записи, или он пустой? Хорошо бы эти вещи проверять перед выполнением. Можете выложить тексты функций GetAccountActivityID и GetAccountFieldID?
Если AccountID пуст, то эта функция даже не выполняется (стоит проверка IsEmptyGUID(AccountID)). Датасет содержит одну запись, как и должно быть (проверял).
Вот тексты функций:
function GetAccountActivityID(ActivityName){if(IsEmptyValue(ActivityName)){return null;}
var ActivityID = GetDatasetIDByFieldValue('ds_Activity', 'Name', ActivityName);if(IsEmptyGUID(ActivityID)){
var ActivityDS = GetSingleItemByCode('ds_Activity', 'ContactIntegration');
ActivityDS.Append();
ActivityID = Connector.GenGUID();
ActivityDS('ID')= ActivityID;
ActivityDS('Name')= ActivityName;
ActivityDS.Post();}return ActivityID;}
function GetAccountFieldID(FieldName){if(IsEmptyValue(FieldName)){return null;}
var FieldID = GetDatasetIDByFieldValue('ds_Field', 'Name', FieldName);if(IsEmptyGUID(FieldID)){
var FieldDS = GetSingleItemByCode('ds_Field', 'ContactIntegration');
FieldDS.Append();
FieldID = Connector.GenGUID();
FieldDS('ID')= FieldID;
FieldDS('Name')= FieldName;
FieldDS.Post();}return ActivityID;}
Михаил, протестировал на Вашей версии. Видимо, Вы вызываете данную функцию в Terrasoft Administrator. Попробуйте выполнять её по какому-то действию из клиентского приложения, должно работать корректно. Данная проблема связана с тем, что во время сохранения сервис датасета находится в режиме редактирования, и в этом состоянии ведёт себя не так, как в рабочем режиме.
Если Вам необходимо обновлять записи именно через Terrasoft Administrator, используйте сервис UpdateQuery.
т.е. пытаюсь отредактировать запись датасета договора с уже существующим заголовком (заголовок сформирован при импорте из Excel значением по умолчанию), выдает следующие
[09.05.21 10.35.06.698] (E) Ошибка выполнения метода 'SelfOnDatasetAfterPost'. Ошибка сохранения записи. Оригинальное сообщение об ошибке: validation error for column Title, value "*** null ***"
The insert failed because a column definition includes validation constraints.
Error Code: 27
INSERT INTO "tbl_Contract" ("ID", "ContractTypeID", "ContractStatusID", "OwnerID", "StartDate", "DueDate", "BillingFrequencyID", "Amount", "BasicAmount", "ModifiedOn", "ModifiedByID", "AllUpgr", "DocWeek1", "DocWeek2", "DocWeek3", "DocWeek4", "DocWeek5", "CreatedOn", "CreatedByID")
VALUES (:ID, :ContractTypeID, :ContractStatusID, :OwnerID, :StartDate, :DueDate, :BillingFrequencyID, :Amount, :BasicAmount, CURRENT_TIMESTAMP, '{94EDBC92-596F-4957-BA05-96A682F739E5}', :AllUpgr, :DocWeek1, :DocWeek2, :DocWeek3, :DocWeek4, :DocWeek5, CURRENT_TIMESTAMP, '{94EDBC92-596F-4957-BA05-96A682F739E5}') «Call Stack»
На сколько я могу судить из текста ошибки, она говорит о том, что в БД поле Title NOT NULL, но идет попытка вставить в это поле значение NULL. Нужно или NOT NULL убрать в дизайнере таблицы, или данные откорректировать.
Да, действительно, поле Title уже заполнено, в скрипте я лишь пытаюсь заполнить поля Amount и BasicAmount, поле Title я вообще не трогаю, оно должно остаться таким как есть
Инсерт идет если датасет пустой. Попробуйте у него вызвать PageRecordsCount() перед вызовом Edit(). Если вернет не 0, то... этого не может быть потому что этого не может быть никогда :)
Посмотрите также состояние датасета передвызовом Edit()
Вы часом не из администратора этот скрипт выполняете????!!!
Нет конечно, данный скрипт, а именно функция (я предоставил ее часть) выполняется из Terrasoft, а именно при удалении или добавлении на деталь продукты в договоре.
Ну вот, я же говорил, что у Вас датасет пустой.
Edit() начинает редактирование текущей записи. Если не было открытия датасета, то записей в нем нет.
"Виталий Ковалишин aka samael" написал:Коллеги, у меня вчера была похожая проблема... Запускал из администратора (в чем разница, где запускать скрипт?)
В администраторе почему-то собираются неправильные запросы. Возможно это сделано для сборки запроса в предпросмотре текста запроса в дизайнере запросов. Но если это так, то автору идеи нужно тоже какую-нибудь каку сделать :)
"Underscore a.k.a. _" написал:В администраторе почему-то собираются неправильные запросы. Возможно это сделано для сборки запроса в предпросмотре текста запроса в дизайнере запросов. Но если это так, то автору идеи нужно тоже какую-нибудь каку сделать :)
"Виталий Ковалишин aka samael" написал:Остается баг с update неясен...
Ну ведь написали:
"Underscore a.k.a. _" написал:В администраторе почему-то собираются неправильные запросы. Возможно это сделано для сборки запроса в предпросмотре текста запроса в дизайнере запросов.
Это именно так. Все связано с тем что если в адиминистраторе мы работаем через Main - то у всех обьектов Connector.IsDesigning = true - в таком случае все объекты ведут себя по другому, в частности датасет всегда возвращает все поля.
В этом случае нужно делать окно, запустать это окно через tscrm.exe /wnd=vashe_okno и на кнопочку в нем выполнять Ваше действие. :) Я именно так всегда и делаю.
Точно , изменение этого свойства у датасета и инсертквери никчему не привело. Но у окон оно вроде работает. Ка-то этот IsDesigning через гланды сделан.
При построении пользовательского отчета MS Word с использованием детали - эта деталь отображается в самом отчете в виде таблицы. В некоторых отчетах это отображение не совсем удобно, особенно в тех случаях, когда необходимо отображение в виде списка.
Могу предложить скрыть рамки таблицы деталей следующим образом:
в скрипте scr_UseReportCommon после строки
var Table = Selection.Tables.Item(1); прописать следующее:
for (var i = 1; i 8; i++) {
Table.Borders(-i).LineStyle = 0;
}
Table.Borders.Shadow = false;
В результате при построении отчетов, рамки таблиц будут невидимы.