Подскажите пожалуйста, как можно обнулить датасет в следующем случае:
var Dataset = GetOpenedDatasetByUSIWithFilter(DatasetUSI, FilterName, ParamValue, UniqueCode, DisableFieldsArray, DoDisableEvents);
var Stop = Dataset('Stop');
if (!IsZeroValue(Stop)) {
MessageBox(Стоит галка Стоп. Запись создана не будет!');
//Здесь перед выходом пробую очистить датасет, но не получается
Dataset.DisableEvents();
Dataset.Close();
return;
}
for(Dataset.GotoFirst(), Counter = 0; ( !Dataset.IsEOF ); Counter++, Dataset.GotoNext()) {
.....
Dataset.Edit();
.....
}
Dataset.Close();
}
Если Stop > 1, то вычисляем какие-то данные и заносим в БД.
Если Stop ==1, то выходим из функции, при этом очищаем датасет.
В случае Stop > 1, все нормально, данные пишутся в БД и при повторном вызове функции дата сет отрабатывает выделенную запись.
Но, если Stop ==1, т.е. мы ничего не хотим писать в БД и просто выйти с очисткой датасета.
Потом, когда заново вызываем функцию, то она начинает отрабатывать предыдущую строку (как-будто датасет не обнулился).
Как его очистить?
Нравится
Алекс, а при отладке перед return какой Dataset,RecordsCount? Не очищается?
"Maxim Gritsenko" написал:Алекс, а при отладке перед return какой Dataset,RecordsCount? Не очищается?
Не очищается. В датасете те строки, в которых при предыдущих вызовах был Stop ==1 и наша текущая строка. Если мы насильно удалим из базы эти строки (где был Stop ==1) или в этих строках сделаем Stop = 0, то из датасета они пропадают.
Что значит очистить датасет? Заполнить все колонки, кроме ID значением null? Удалить запись? Не совсем понятно... Опишите, пожалуйста, Вашу бизнес задачу.
Если у вас точно известно, что
var Dataset = GetOpenedDatasetByUSIWithFilter(DatasetUSI, FilterName, ParamValue, UniqueCode, DisableFieldsArray, DoDisableEvents);
вернет одну строку (к примеру вы фильтруете по ID), то пишем просто:
if(!Stop) { //пишем данные }
если это точно не известно то в цикле:
while(!Dataset.IsEOF) { var Stop = Dataset('Stop'); if(!Stop) { Dataset.Edit(); ... Dataset.Post(); } Dataset.GotoNext(); }
пс: мне кажется, что функция GetOpenedDatasetByUSIWithFilter возвращает старый экземпляр датасета. Может поможет если напишите явно?
var Dataset = Services.GetNewItemByUSI('ds_Stop'); EnableDatasetFilters(Dataset, false); ApplyDatasetFilter(Dataset, 'FilterName', FilterValue, true); Dataset.Open(); ....
"Олейник Дмитрий" написал:пс: мне кажется, что функция GetOpenedDatasetByUSIWithFilter возвращает старый экземпляр датасета. Может поможет если напишите явно?
var Dataset = Services.GetNewItemByUSI('ds_Stop');
EnableDatasetFilters(Dataset, false);
ApplyDatasetFilter(Dataset, 'FilterName', FilterValue, true);
Dataset.Open();
....С уважением,
Олейник Дмитрий
На GetOpenedDatasetByUSIWithFilter очень много завязано, поэтому поменять на GetNewItemByUSI просто не получится.
Вот последовательность действий:
Если на выделенной строке (ID=A1) в мастере Stop <> 1, то пишутся в базу некие данные в деталь. Датасет А1.
Если на выделенной строке (ID=A2) в мастере Stop <> 1, то пишутся в базу некие данные в деталь. Датасет А2.
Если на выделенной строке (ID=A3) в мастере Stop == 1, то НЕ пишем в базу данные в деталь и показываем окно-предупреждение, что Stop == 1 и ничего нельзя писать в БД. Датасет А3.
Если на выделенной строке (ID=A4) в мастере Stop <> 1, то пишутся в базу некие данные в деталь. При этом dataset обращается к ID = A3, обрабатывает, затем к A4. Т.е. A3 сохраняется в датасете. Датасет А3, А4.
Если же теперь мы в A3 сделаем Stop <> 1 и отработаем эту строку. То она исчезает из дата сета. Датасет А3.
Если на выделенной строке (ID=A5) в мастере Stop <> 1, то пишутся в базу некие данные в деталь. Датасет А5.
Есть ли какой-нибудь способ принудительной очистки данного датасета в этом случае?
Пробовал вариант:
if(!Stop) { //пишем данные }
Но то же самое.
Правильно ли я понял, что выделенная строка с разными ID - это строки, которые попали в датасет после его открытия через GetOpenedDatasetByUSIWithFilter ?
Если так, то по этому датасету вы ходите в цикле и при определенных условиях что-то пишете в детали? Каким образом с 4-ой строки вы перемещаетесь на 3-ую, и снова на 4-ую?
Если же теперь мы в A3 сделаем Stop <> 1
т.е. вся обработка не в один "присест", а по какому либо событию, и датасет вы каждый раз получаете новый?
В общем, все-ровно не понял как это все у вас устроено. Можете прикрепить весь свой код сюда полностью, а также объясните, пожалуйста, все таки: все эти строки обрабатываются в одном цикле, или эта функция вызывается несколько раз? Если несколько - то с какими параметрами, и меняете ли Вы uniqueCode для датасета? Сбрасываются ли фильтра?
Более подробно:
Выбираю строку в гриде. В контекстном меню - Действия - ВыполнитьДействие. Попадаем сюда:
function amiOnExecute(ActionMenuItem, Sender) { var OpDataset = dlOp.Dataset; //Уже сюда вынес проверку на Stop var Stop = OpDataset('Stop'); if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); //Здесь пытаюсь очистить датасет, как-будто я не выбирал строку в гриде (но не чистит) OpDataset.Close(); OpDataset.Open(); return false; } var Result = hConfirmation(OpDataset, OpWorkspace.COpWindow); }
Далее следующая функция для проверки:
function hConfirmation(OpDataset, ParentWindow) { var Message = FormatStr('Вы действительно хотите ...' , GetSystemParameterValueEx('ToPay', true)); if (ShowConfirmationDialog(Message) != wmrYes) { return; } finalEv(OpDataset, ParentWindow); }
И наша финальная функция, которая отрабатывает и пишет в базу:
function finalEv(OpDataset, ParentWindow) { var DatasetUSI = 'ds_COp'; var Dataset = GetOpenedDatasetByUSIWithFilter(DatasetUSI, 'CanEv', true, 'finalEv', null, true); .... //Вот в этом цикле пишутся данные в БД. for(Dataset.GotoFirst(), Counter = 0; ( !Dataset.IsEOF ); Counter++, Dataset.GotoNext()) { ..... Dataset.Edit(); ..... } Dataset.Close(); }
Хотелось бы, если Stop ==1, то выходим из функции, при этом очищаем датасет.
Судя по всему GetOpenedDatasetByUSIWithFilter запоминает строку (OLD), когда мы отрабатывали:
function amiOnExecute(ActionMenuItem, Sender) { var OpDataset = dlOp.Dataset; //Уже сюда вынес проверку на Stop var Stop = OpDataset('Stop'); if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); //Здесь пытаюсь очистить датасет, как-будто я не выбирал строку в гриде (но не чистит) OpDataset.Close(); OpDataset.Open(); return false; } var Result = hConfirmation(OpDataset, OpWorkspace.COpWindow); }
и при выполнения Действия над другой новой (new) строкой (где Stop <>1) сначала выполняется обработка этой new строки (мы её просто выбираем в гриде), а затем тут же отрабатывается наша OLD строка.
Как очистить датасет от этой (этих) OLD строк, как будто их вообще небыло?
Это
OpDataset.Close();
OpDataset.Open();
не помогает.
Что-то такое
OpDataset.Clear();
не поддерживается?
function amiOnExecute(ActionMenuItem, Sender) { var OpDataset = dlOp.Dataset; var Stop = OpDataset('Stop'); if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); return false; } var Result = hConfirmation(OpDataset, OpWorkspace.COpWindow); }
Переоткрывать датасет
OpDataset.Close(); OpDataset.Open();
не имеет смысла, т.к. при открытии вы всегда будете позиционированы на первой строке. Т.е.
function Main() { var Dataset = Services.GetNewItemByUSI('ds_CommunicationType'); Dataset.Open(); //Dataset.RecordNumber == 1; Dataset.GotoNext(); //Dataset.RecordNumber == 2; Dataset.Close(); Dataset.Open(); //Dataset.RecordNumber == 1; }
таким образом датасет не будет помнить на какой строке вы были до этого. Кроме того визуально в реестре выделена будет первая запись, а не та, которая была выбрана изначально перед запуском действия. И хотя, это здесь не причем, т.к. после этого стоит return, и при последующем запуске действия, вы скорее всего новую выберите нужную строку и датасет заново будет позиционирован, но все же.
Таким образом, что мы имеем:
первую функцию-действие лучше переписать так:
function amiOnExecute(ActionMenuItem, Sender) { var OpDataset = dlOp.Dataset; var Stop = OpDataset('Stop'); if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); return false; } var Result = hConfirmation(OpDataset, OpWorkspace.COpWindow); }
функция hConfirmation будет выполнена только в том случае, если в текущей выделенной строке, для которой было запущено действие, поле Stop не заполнено.
Вторая функция остается без изменений:
function hConfirmation(OpDataset, ParentWindow) { var Message = FormatStr('Вы действительно хотите ...' , GetSystemParameterValueEx('ToPay', true)); if (ShowConfirmationDialog(Message) != wmrYes) { return; } finalEv(OpDataset, ParentWindow); }
а вот с третьей непонятно. Самое интересное то, что вы ей передаете датасет реестра (OpDataset), который позиционирован на нужной строке (т.е. та в которой стоп = 0), а также ParentWidnow, но при этом нигде их не используете. Покажите как Вы его используете, потому что в текущем примере OLD строка никак не может быть обработана, если вы не выполняете никаких манипуляций , которые приводят к смене текущей активной строки, что-то вроде этого:
OpDataset.GotoNext();
OppDataset.Close(); OppDataset.Open();
пс: могу предложить не передавать никаких датасетов (т..к скорее всего вы где-то там запутались), а передать сразу нужные значения, которые вы собираетесь использовать, в функцию записи данных в БД. Что-то вроде:
function amiOnExecute(ActionMenuItem, Sender) { var OpDataset = dlOp.Dataset; var Stop = OpDataset('Stop'); if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); return false; } var myValue1 = OppDataset('myVaule1'); var myValue2 = OppDataset('myVaule2'); var myValue3 = OppDataset('myVaule3'); var Result = hConfirmation(myValue1,myValue2, myValue3, OpWorkspace.COpWindow); }
"Олейник Дмитрий" написал:а вот с третьей непонятно. Самое интересное то, что вы ей передаете датасет реестра (OpDataset), который позиционирован на нужной строке (т.е. та в которой стоп = 0), а также ParentWidnow, но при этом нигде их не используете. Покажите как Вы его используете, потому что в текущем примере OLD строка никак не может быть обработана, если вы не выполняете никаких манипуляций , которые приводят к смене текущей активной строки, что-то вроде этого:
OpDataset.GotoNext();
OppDataset.Close();
OppDataset.Open();пс: могу предложить не передавать никаких датасетов (т..к скорее всего вы где-то там запутались), а передать сразу нужные значения, которые вы собираетесь использовать, в функцию записи данных в БД. Что-то вроде:
function amiOnExecute(ActionMenuItem, Sender) {
var OpDataset = dlOp.Dataset;
var Stop = OpDataset('Stop');
if (!IsZeroValue(Stop)) {
MessageBox('Стоит галка Stop ! Ничего в базу не пишем!');
return false;
}
var myValue1 = OppDataset('myVaule1');
var myValue2 = OppDataset('myVaule2');
var myValue3 = OppDataset('myVaule3');
var Result = hConfirmation(myValue1,myValue2, myValue3, OpWorkspace.COpWindow);
}С уважением,
Олейник Дмитрий
Манипуляции выполняются в этом цикле:
//Вот в этом цикле пишутся данные в БД. for(Dataset.GotoFirst(), Counter = 0; ( !Dataset.IsEOF ); Counter++, Dataset.GotoNext()) { ..... Dataset.Edit(); ..... } Dataset.Close(); }
Сначала выполняется текущая активная строка грида с Stop=0(null), а затем в этом цикле выполняется OLD строка (с Stop=1), которую вроде бы как мы покинули здесь:
if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); return false; }
Напрямую передавать параметры не получится, т.к. они вычисляются и связаны с другими ds.
Можно ли очистить наш OpDataset вообще как-нибудь, что-бы там не было никаких строк old?
И если можно, то в этом месте
if (!IsZeroValue(Stop)) { MessageBox('Стоит галка Stop ! Ничего в базу не пишем!'); // Здесь очищаем наш дата сет от нашей строки, которая попала сюда. return false; }
Думаю, Вам стоит передать обезличенную копию БД или сервисы в поддержку. Без этого долго воспроизводить придется.