Подскажи, как можно сделать массовое добавление записей?

У меня есть таблица, в ней есть записи, мне нужно по фильтру выбрать записи которых нет во второй таблице, потом отфильтровать по городу, и указать что нужно определенное количество записей из каждого указанного города записать в другую таблицу.

Код выполняется на сервере, в конфигурационном сервисе.

Нравится

3 комментария

Александр, у элемента вставки в БП есть возможность вставлять выборку из другого объекта с нужным фильтром.

Из того, что Вы хотите, нет разве что указания количества. Возможно, получится через view с привязанным объектом, там в SQL-запросе можно сразу прописать и фильтр, и количество.

 

Ну или всю логику и считывания, и вставки реализовать в C#-скрипте с использованием классов ESQ или Select и Insert.

Зверев Александр, Реализовать надо в сервисе, выходит только через Select

Query selectQuery = new Select(UserConnection).Top(numberCountForNumberPool)
	.Column(Column.Parameter(request)).Column(Column.Parameter(currentUserContactId))
	.Column(Column.Parameter(currentUserContactId))
	.Column("KtSimManagementInitialPoolNumbers", "KtIccid")
	.Column("KtSimManagementInitialPoolNumbers", "KtImsi")
	.Column("KtSimManagementInitialPoolNumbers", "KtMsisdn")
	.Column("KtSimManagementInitialPoolNumbers", "KtName")
	.Column(Column.Parameter(cityAndCountNumbersEntity.GetTypedColumnValue<Guid>(city.Name)))
	.Column(Column.Parameter(cityAndCountNumbersEntity.GetTypedColumnValue<string>(note.Name)))
	.Column(Column.Parameter(DateTime.UtcNow.Date))
	.Column(Column.Parameter(DateTime.UtcNow.Date
		.AddDays((int)Core.Configuration.SysSettings.GetValue(UserConnection,
			"DayCountForDedicatedPoolNumbers") + 1).AddSeconds(-1)))
	.From("KtSimManagementInitialPoolNumbers")
	.OrderByAsc("KtSimManagementInitialPoolNumbers", "KtName")
	.Join(JoinType.LeftOuter, "KtJasperFullNumberPool")
	.On("KtSimManagementInitialPoolNumbers", "KtName")
	.IsEqual("KtJasperFullNumberPool", "KtName")
	.Where("KtJasperFullNumberPool", "KtName")
	.IsNull()
	.And("KtSimManagementInitialPoolNumbers", "KtMarketCodeId")
	.IsEqual(Column.Parameter(cityForMarketCode));
InsertSelect insertSelectQuery = new InsertSelect(UserConnection)
	.Into("KtJasperFullNumberPool")
	.Set("KtRequestId", "ModifiedById", "CreatedById", "KtIccid", "KtImsi", "KtMsisdn", "KtName", "KtCityId", "KtNote", "KtReserveDate", "KtReserveToDate")
	.FromSelect(selectQuery);
int numberCountInserted = insertSelectQuery.Execute();

И все работает отлично, но на PostgreSQL, при установке на версию для Oracle ругается 

"ERROR IIS APPPOOL\CreatioCRMOracle Terrasoft.Web.Common.ServiceModel.ErrorHandler ProvideFault - Псевдоним колонки запроса не может быть пустым".

 

Что бы понятно было - конфигурации полностью одинаковые, просто dev среда на PostgreSQL а Prod на Oracle. И вот найти проблему тут уже не как не выходит

А на какое именно место в коде ругается? Если просто Select, без Insert, то тоже? Попробуйте последовательно запускать Select без разных колонок, чтобы выяснить, в какой из них дело.

Показать все комментарии

Добрый день.
У меня в разделе Операции есть созданная деталь PaymentInCashflowDetail, которая позволяет добавлять записи для связи с новым разделом Payment. Есть карточка добавления на деталь новой записи. В ней всего три поля - собственно Операция, запись раздела Payment, и тип их отношения (выбор из справочника). Все хорошо работает.
Проблема в рутине заполнения. Потому что например надо пройтись по деталям 40 операций и внести туда однотипную связь. А потом пройтись по еще 30 и добавить еще одну однотипную связь. И так далее.

Поэтому вопрос как изменить стандартно работающую деталь таким образом, чтобы при выборе в реестре нескольких Операций после добавления записи на деталь она добавлялась для всех выбранных операций?

P.S. В коробочной версии нет ни одной детали , которая бы работала таким образом.
Когда-то , используя материалы форума (никак не могу найти ту тему), я вносила изменения в стандартную деталь Доступ, и поэтому при выборе нескольких записей в реестре, указанный доступ раздается сразу на все выбранные записи. Возможно дело в специфике детали Доступ, но аналогичным образом изменить мою созданную деталь не получается.

Нравится

9 комментариев

Здравствуйте, Виктория!

Уточните, пожалуйста, какую версию продукта Вы используете? Если разговор идет о версии выше 3.4.0.x то данный функционал присутствует в базовой логике. Например можно добавлять по нескольким записям пользователей на деталь "Доступ". Соответственно, реализацию можно посмотреть в базовой конфигурации. Если же версия клиента, ниже 3.4, то там навряд ли получится реализовать такую вещь, так частично данный функционал используется в ядре.

версия 3.3.2.
И даже в ней я делала добавление на детали Доступ сразу по нескольким записям. Но так же не получается сделать здесь

А чем не устраивает тупо в лоб действовать?
1) Добавить на гриде детали кнопку "Добавить для выделенных" (можно даже объединить ее с кнопкой "Добавить", ну как "Удалить" и "Удалить все")
2) Считать с главного реестра id выделенных записей и записать их в массив IDs
3) На кнопку "Добавить для выделенных" поставить логику запуска окна карточки добавления на деталь, добавив параметр IDs
4) Переопределить логику кнопки OK (если параметр пуст или нет такого, то действуй как обычная кнопка ОК, если что-то есть то пройтись по всем id и добавить)

Это решение чуть отличается от изначального, но может ускорить процесс заполнения.
Поэтому пробую.
Сделала новую кнопку, описала что будет происходить по ее нажатию

function btnAddOnDetailOnClick(Control) {
 
	 var ArrayIDs = GetArrayByCollection(grdData.SelectedIDs);
 var Attributes = GetNewDictionary();
 	AddRequiredValuesToDictionary(Attributes, GUID_NULL, true, BaseGridArea);
	for (i = 0; i < ArrayIDs.length; i++) {
	var SourceRecordID = ArrayIDs[i];
	Attributes('SourceRecordID') = SourceRecordID;
 
	   }
 	var DefaultValues = GetNewDictionary();
  	ShowEditWindowEx('wnd_PaymentInCashflowEdit',Attributes, DefaultValues);
}

Видимо уже что-то неверно , потому что окно открывается, но оно не активно, и возникает сообщение "Ошибка копирования записи. Оригинальное сообщение об ошибке: запись удалена".

Здравствуйте, Виктория!
Неправильно передаете аттрибуты. У Вас в итоге получается, что в Attributes('SourceRecordID') будет ID последней выделенной записи.
Лучше сделать так, например:

var SelectedIDs = new ActiveXObject('TSObjectLibrary.StringsList');
SelectedIDs.AssignObject(grdData.SelectedIDs);
Attributes('SelectedIDs') = SelectedIDs;

Андрей, вы правы, но это не объясняет почему "Ошибка копирования записи. Оригинальное сообщение об ошибке: запись удалена". Строчка AddRequiredValuesToDictionary(Attributes, GUID_NULL, true, BaseGridArea); не нужна, как раз из-за нее, наверное, эта ошибка.

Виктория, вопрос уже к вам, где вы поставили кнопку, на гриде раздела или в детали?
Я считаю ее правильно все таки на разместить на детали.
Чтобы взять и передать все id в окно wnd_PaymentInCashflowEdit используйте такой скрипт (надеюсь, что разъяснять что есть что не надо)

var MainWindow = Connector.Attributes('MainWindow');
var WorkspaceWindow = MainWindow.ComponentsByName('wndWorkspace').Window;
var wndGridData = WorkspaceWindow.ComponentsByName('wndGridData').Window;
var grdDataAccount = wndGridData.ComponentsByName('grdData');
var SelectedIDs = grdDataAccount.SelectedIDs.CommaText.split(',');
var Attributes = GetNewDictionary();
Attributes('NotifyObject') = Self;
Attributes('SelectedIDs') = SelectedIDs;   
var DefaultValues = GetNewDictionary();
ShowEditWindowEx('wnd_PaymentInCashflowEdit',Attributes, DefaultValues);

В wnd_PaymentInCashflowEdit допишите на кнопку ОК скрипт (точнее немного переделать)

if (Self.Attributes('SelectedIDs') == null) {
	//Нет такого атрибута, значит действует как обычная кнопка ОК
	//Сюда вписать то, что было на этой кнопке, скорее всего просто scr_BaseDBEdit.btnOKOnClick(Control);
} else {
	//здесь добавляем ко всем выделенным записям
	//можно через Append-Post, можно через Insert Query, можете придумать еще какой-то способ
	//пример с Append-Post
	var Dataset = dlData.Dataset;
	var PaymentDataset = Services.GetNewItemByUSI('ds_AccountIndustry') //замените на свой датасет детали
	for (var i = 0; i < Self.Attributes('SelectedIDs').length; i++) {
		//по одной добавляем записи
		PaymentDataset.Append();			
                //тут пройдем по всем полям на окне
		for(var j = 0; j < Self.ComponentCount; ++j) {
			var Field = Self.Components(j);
			if (Field.DataFieldName) {
				PaymentDataset(Field.DataFieldName) = Dataset(Field.DataFieldName);
			}
		}
		PaymentDataset('AccountID') = Self.Attributes('SelectedIDs')[i]; //AccountID - замените на свое поле
		PaymentDataset.Post();
	}
        //закрываем окно
	PaymentDataset = null;
	Self.Close();
        //обновляем датасет на детали
	var NotifyObject = Self.Attributes('NotifyObject');
	var DetailDataset = NotifyObject.ComponentsByName('dlData').Dataset;
	DetailDataset.Close();
	DetailDataset.Open();
}

Продвигаюсь к цели. Исправила здесь.

function btnAddOnDetailOnClick(Control) {
 
	 var ArrayIDs = GetArrayByCollection(grdData.SelectedIDs);
 var Attributes = GetNewDictionary();
 
 
 var SelectedIDs = new ActiveXObject('TSObjectLibrary.StringsList');
SelectedIDs.AssignObject(grdData.SelectedIDs);
Attributes('SelectedIDs') = SelectedIDs;
 
 		var DefaultValues = GetNewDictionary();
  	ShowEditWindowEx('wnd_PaymentInCashflowEdit',Attributes, DefaultValues);
}

Создала специальный InsertQuery. Теперь пишу код для кнопки ОК.

var InsertObject = {};
 
function btnOKOnClick(Control) {
	var Dataset = dlData.Dataset;
 
		 var Attributes = GetNewDictionary();
		Attributes = Self.Attributes('SelectedIDs');
 
if 	(!IsEmptyValue(Attributes)) {
		for (i = 0; i < Attributes.length; i++) {
 
           var PaymentID = Dataset.Values('PaymentID');
	       var PrincipleID = Dataset.Values('PrincipleID');
	       var ContactID = Connector.CurrentUser.ContactID;
           var CashflowID = Attributes[i];
 
           	if (!Assigned(InsertObject.iq_Insert)) {
		     InsertObject.iq_Insert = Services.GetNewItemByUSI('iq_InsertPaymentInCashflow');
	               }
	var IQ = InsertObject.iq_Insert;
	IQ.ColumnsValues('ID').Value = Connector.GenGUID();
	IQ.ColumnsValues('PaymentID').Value = PaymentID;
    IQ.ColumnsValues('PrincipleID').Value = PrincipleID;
    IQ.ColumnsValues('CashflowID').Value = CashflowID;
      IQ.ColumnsValues('ModifiedByID').Value = ContactID;
    IQ.Execute();
}  
 
 
}   else {
 scr_BaseDBEdit.btnOKOnClick(Control);
 }
		    }
 

Дает открыть окно, заполнить значения.
Но по нажатию кнопки просто ничего не происходит и даже окно не закрывается.

Виктория, очевидно, Вы не добавили функцию закрытия окна после выполнения InsertQuery.
Во-первых, нужно закрывать окно после выхода из цикла. Во-вторых, не уверен, что Self.Attributes('SelectedIDs'); в Вашем случае корректно обрабатывается. попробуйте так:

var InsertObject = {};
 
function btnOKOnClick(Control) {
    var Dataset = dlData.Dataset;
 
    var SelectedIDs = Window.Attributes('SelectedIDs');
    if ((IsEmptyValue(SelectedIDs)) || (SelectedIDs.Count == 0)) {
        scr_BaseDBEdit.btnOKOnClick(Control);
    }
    else {
        for (i = 0; i < SelectedIDs.Count; i++) {
            var PaymentID = Dataset.Values('PaymentID');
            var PrincipleID = Dataset.Values('PrincipleID');
            var ContactID = Connector.CurrentUser.ContactID;
            var CashflowID = SelectedIDs.Items(i);
 
            if (!Assigned(InsertObject.iq_Insert)) {
                InsertObject.iq_Insert = Services.GetNewItemByUSI('iq_InsertPaymentInCashflow');
            }
            var IQ = InsertObject.iq_Insert;
            IQ.ColumnsValues('ID').Value = Connector.GenGUID();
            IQ.ColumnsValues('PaymentID').Value = PaymentID;
            IQ.ColumnsValues('PrincipleID').Value = PrincipleID;
            IQ.ColumnsValues('CashflowID').Value = CashflowID;
            IQ.ColumnsValues('ModifiedByID').Value = ContactID;
            IQ.Execute();
        }
        Self.Close();
    }
}

Поменяла все же
var SelectedIDs = Window.Attributes('SelectedIDs'); на
var SelectedIDs =Self.Attributes('SelectedIDs');

И так теперь все работает! Спасибо всем, кто помогал.

Показать все комментарии