Добрый день.
У меня следующая задача:

По изменению записи на детали нужно изменять состояние записи основного раздела.

Проблема состоит в том, что пользователь, который изменяет запись на детали имеет права к записи раздела "только чтение". Соответственно он не может изменить ее состояние.
Вопрос в том, можно ли это как то обойти не используя триггеры?

И еще одно. Почему кода я делаю Dataset.Post() под этим пользователем все вроде срабатывает, то есть Post не дает ни какой ошибки, состояние возвращается в начальное только после Dataset.RefreshRecord, или после его переодкрытия.

Нравится

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

"Домброва Михаил" написал:Вопрос в том, можно ли это как то обойти не используя триггеры?

Можно хранимые процедуры, но, думаю, это Вы и имели ввиду.
"Домброва Михаил" написал:состояние возвращается в начальное только после Dataset.RefreshRecord, или после его переодкрытия.

Не совсем понял, что есть начальное состояние.

"Кулак Олег" написал:Не совсем понял, что есть начальное состояние.

Имеется в веду, что исходное состояние записи было "Визирование", а нужно изменять на "Отправлено"

Я бы склонялся к варианту использования средств СУБД.

имхо правильный путь настроить грамотно права пользователей на поля - конкретно на поле состояние дать право редактирования, на остальные только чтение, и не надо будет проделывать дырки в безопасности

Наверное сделаю на триггере, т.к. у меня права раздаются тоже на них.

"Александр Кудряшов" написал:имхо правильный путь настроить грамотно права пользователей на поля - конкретно на поле состояние дать право редактирования, на остальные только чтение, и не надо будет проделывать дырки в безопасности

Поддерживаю. Права доступа на поля таблицы для таких случаев и созданы.

И не забываем работать исключительно через группы пользователей, даже если он там один :)

А через группы не выйдет, т.к. в моем случае, если пользователь добавлен на деталь "Кому/Копия", "Визирование" или "Резолции", ему выдетяются права на чтение записи раздела, если же его удалить, то права отбераются, при чем ответственный записи раздела при разних значениях ее поля "Состояние" тоже имеет разные права. Вот такая процедура раздачи прав:smile:

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

Добрый день!

Подскажите, пожалуйста, правильный (наиболее эффективный в плане производительности) способ копирования данных из одного Dataset'a в другой, при условии, что копировать нужно все подряд данные, но только часть полей (объём данных достаточно большой).

Спасибо.

Нравится

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

А какая предыстория у этой задачи. То есть, какой функционал хотите реализовать?

Первый из датасетов создается динамически при импорте заявок из xml файлов. Второй - лог операций после обработки заявок из первого датасета, и привязан к физической таблице.

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

Ну если смотреть в сторону производительности, то я думаю в вашем случаю будет удобно использовать insertquery как в первой так и второй задаче.
Если ветка относится ко второй задаче, то я ответил по варианту получения текста запроса для обработки его результатов напрямую на сервере.

За подсказку с insertquery большое спасибо :)

Все же, а что если требуется скопировать и потом по некоторым полям тут же внести изменения?
(Все операции логируются, не хотелось бы выполнять Insert а потом Update, а перед вставкой модифицировать некоторые поля)?

Можно примерчик кода, пожалуйста?

Здравствуйте,
1)Например так :

function Main()
{
var ds_to = Services.GetNewItemByUSI('ds_to');
var ds_from = Services.GetNewItemByUSI('ds_from');
 
 
	ds_from.Open();
 
	ds_to.Open();
	while(!ds_from.IsEOF) {
	ds_to.Edit();
	ds_to('ID')  = ds_from('ID');
	ds_to('Name') = ds_from('Name');
	ds_to.Post();
	ds_to.Close();
	ds_from.GotoNext();
	}	
 
	ds_from.Close();
}

В случае если Вы хотите генерировать новые ID, используйте Connector.GenGUID();

ds_to('ID')  = Connector.GenGUID();

2) Второй способ, это подключить scr_DB и воспрользоваться функцией CopyFullData(SourceDataset, DestinationDataset)
При этом вы получите точную копию данных датасетов
Пример:

var ds_to = Services.GetNewItemByUSI('ds_to');
var ds_from = Services.GetNewItemByUSI('ds_from');
ds_to.Open();
ds_from.Open();
CopyFullData(ds_from, ds_to);

Спасибо, Алексей,

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

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

В скрипте нужно выбрать записи из ds_InvoiceVises с определенным InvoiceID. Как это можно сделать. В SDK нашел свойство IsFiltered, а вот как указать какой фильтр и какое значение параметра для фильтра?

Нравится

2 комментария
var InvoiceID = 'Needed_GUID'
var ds_InvoiceVises = Services.GetNewItemByUSI('ds_InvoiceItems');
ApplyDatasetFilter(ds_InvoiceVises, 'InvoiceID', InvoiceID, true);
ds_InvoiceVises.Open();

не забудьте в скрипт подключить scr_DB

Попробуйте воспользоваться методом ApplyDatasetIDFilter(Dataset, IDValue, Enabled)из скрипта scr_DB.

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

Доброго дня!
Имеется следующий кусок кода, в котором происходит выборка по трём фильтрам и изменение одного поля датасета. Параметры передаются правильные, выборка проходит корректно, в MessageBox отображается измененнное значение, но в базе ничего не меняется.

        var ProductID = dlData.Dataset.Values('ID');
        var ReceiptDataset = Services.GetNewItemByUSI('ds_ProductInMovement');
        ApplyDatasetFilter(ReceiptDataset, 'ProductID', ProductID, true);
        ApplyDatasetFilter(ReceiptDataset, 'StoreID', StoreID, true);
        ApplyDatasetFilter(ReceiptDataset, 'TypeID', TypeID, true);
        ReceiptDataset.Open();
       
        if (ReceiptDataset.RecordsCount>0)
        {
                ReceiptDataset.GotoFirst();
                ReceiptDataset.Edit();
                ReceiptDataset.ValAsFloat('ActualQuantity') = 0;
                ReceiptDataset.Post();

                var Message = "Q=" + ReceiptDataset.ValAsFloat('ActualQuantity');

                ReceiptDataset.Close();
                ShowWarningDialog(Message);
        }      

Пожалуйста, помогите разобраться в чём дело. Редактирование данных через соответствущее окно, завязанное на данный датасет, проходит нормально.

Нравится

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

Покажите, что показывает профайлер при выполнении ReceiptDataset.Post();.

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

Проверьте, какая основная таблица в ReceiptDataset.SelectQuery (та ли, в которой поле ActualQuantity)

А также, не сбилась ли привязка поля в SelectQuery

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

var ProductID = dlData.Dataset.Values('ID');
 
        var ReceiptDataset = Services.GetNewItemByUSI('ds_ProductInMovement');
 
        ApplyDatasetFilter(ReceiptDataset, 'ProductID', ProductID, true);
 
        ApplyDatasetFilter(ReceiptDataset, 'StoreID', StoreID, true);
 
        ApplyDatasetFilter(ReceiptDataset, 'TypeID', TypeID, true);
 
        ReceiptDataset.Open();
 
 
 
        while (ReceiptDataset.IsEOF) {
 
                ReceiptDataset.Edit();
 
                ReceiptDataset.ValAsFloat('ActualQuantity') = 0;
 
                ReceiptDataset.Post();
 
 
 
                ReceiptDataset.GotoNext();
 
            }
 
        ReceiptDataset.Close();

"Татьяна Адамчук" написал:Сергей, если по указанному фильтру открывается источник данных, содержит несколько строк и для каждой необходимо обнулить указанное поле, то можно написать следующим образом:

еще надо отключить AutoRefresh

ReceiptDataset.AutoRefresh = false;

и условие в while -> !ReceiptDataset.IsEOF

Спасибо за помощь, проблема крылась в коварном триггере, который пересчитывал заново значение поля.

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

Пример по subj

var Dataset = Services.GetNewItemByUSI('ds_Contact');
Dataset.Open();

var Stream = new ActiveXObject('ADODB.Stream');
Stream.Type = 1;
Stream.Mode = 3;
Stream.Open();

Dataset.SaveToXML(Stream);
Dataset.Close();

Stream.SaveToFile('D:\\Data.xml');
Stream.Close();

Нравится

Поделиться

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