Подскажите пожалуйста, как можно обнулить датасет в следующем случае:
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? Удалить запись? Не совсем понятно... Опишите, пожалуйста, Вашу бизнес задачу.
Если у вас точно известно, что
[javascript]
var Dataset = GetOpenedDatasetByUSIWithFilter(DatasetUSI, FilterName, ParamValue, UniqueCode, DisableFieldsArray, DoDisableEvents);
[/javascript]
вернет одну строку (к примеру вы фильтруете по ID), то пишем просто:
[javascript]
if(!Stop) {
//пишем данные
}
[/javascript]
если это точно не известно то в цикле:
[javascript]
while(!Dataset.IsEOF) {
var Stop = Dataset('Stop');
if(!Stop) {
Dataset.Edit();
...
Dataset.Post();
}
Dataset.GotoNext();
}
[/javascript]
пс: мне кажется, что функция GetOpenedDatasetByUSIWithFilter возвращает старый экземпляр датасета. Может поможет если напишите явно?
[javascript]
var Dataset = Services.GetNewItemByUSI('ds_Stop');
EnableDatasetFilters(Dataset, false);
ApplyDatasetFilter(Dataset, 'FilterName', FilterValue, true);
Dataset.Open();
....
[/javascript]
"Олейник Дмитрий" написал:пс: мне кажется, что функция 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.
Есть ли какой-нибудь способ принудительной очистки данного датасета в этом случае?
Пробовал вариант:
[javascript]
if(!Stop) {
//пишем данные
}
[/javascript]
Но то же самое.
Правильно ли я понял, что выделенная строка с разными ID - это строки, которые попали в датасет после его открытия через GetOpenedDatasetByUSIWithFilter ?
Если так, то по этому датасету вы ходите в цикле и при определенных условиях что-то пишете в детали? Каким образом с 4-ой строки вы перемещаетесь на 3-ую, и снова на 4-ую?
[code]
Если же теперь мы в A3 сделаем Stop <> 1
[/code]
т.е. вся обработка не в один "присест", а по какому либо событию, и датасет вы каждый раз получаете новый?
В общем, все-ровно не понял как это все у вас устроено. Можете прикрепить весь свой код сюда полностью, а также объясните, пожалуйста, все таки: все эти строки обрабатываются в одном цикле, или эта функция вызывается несколько раз? Если несколько - то с какими параметрами, и меняете ли Вы uniqueCode для датасета? Сбрасываются ли фильтра?
Более подробно:
Выбираю строку в гриде. В контекстном меню - Действия - ВыполнитьДействие. Попадаем сюда:
[javascript]
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);
}
[/javascript]
Далее следующая функция для проверки:
[javascript]
function hConfirmation(OpDataset, ParentWindow)
{
var Message = FormatStr('Вы действительно хотите ...' ,
GetSystemParameterValueEx('ToPay', true));
if (ShowConfirmationDialog(Message) != wmrYes) {
return;
}
finalEv(OpDataset, ParentWindow);
}
[/javascript]
И наша финальная функция, которая отрабатывает и пишет в базу:
[javascript]
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();
}
[/javascript]
Хотелось бы, если Stop ==1, то выходим из функции, при этом очищаем датасет.
Судя по всему GetOpenedDatasetByUSIWithFilter запоминает строку (OLD), когда мы отрабатывали:
[javascript]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);
}
[/javascript]
и при выполнения Действия над другой новой (new) строкой (где Stop <>1) сначала выполняется обработка этой new строки (мы её просто выбираем в гриде), а затем тут же отрабатывается наша OLD строка.
Как очистить датасет от этой (этих) OLD строк, как будто их вообще небыло?
Это
OpDataset.Close();
OpDataset.Open();
не помогает.
Что-то такое
OpDataset.Clear();
не поддерживается?
[javascript]
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);
}
[/javascript]
Переоткрывать датасет
[javascript]
OpDataset.Close();
OpDataset.Open();
[/javascript]
не имеет смысла, т.к. при открытии вы всегда будете позиционированы на первой строке. Т.е.
[javascript]
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;
}
[/javascript]
таким образом датасет не будет помнить на какой строке вы были до этого. Кроме того визуально в реестре выделена будет первая запись, а не та, которая была выбрана изначально перед запуском действия. И хотя, это здесь не причем, т.к. после этого стоит return, и при последующем запуске действия, вы скорее всего новую выберите нужную строку и датасет заново будет позиционирован, но все же.
Таким образом, что мы имеем:
первую функцию-действие лучше переписать так:
[javascript]
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);
}
[/javascript]
функция hConfirmation будет выполнена только в том случае, если в текущей выделенной строке, для которой было запущено действие, поле Stop не заполнено.
Вторая функция остается без изменений:
[javascript]
function hConfirmation(OpDataset, ParentWindow)
{
var Message = FormatStr('Вы действительно хотите ...' ,
GetSystemParameterValueEx('ToPay', true));
if (ShowConfirmationDialog(Message) != wmrYes) {
return;
}
finalEv(OpDataset, ParentWindow);
}
[/javascript]
а вот с третьей непонятно. Самое интересное то, что вы ей передаете датасет реестра (OpDataset), который позиционирован на нужной строке (т.е. та в которой стоп = 0), а также ParentWidnow, но при этом нигде их не используете. Покажите как Вы его используете, потому что в текущем примере OLD строка никак не может быть обработана, если вы не выполняете никаких манипуляций , которые приводят к смене текущей активной строки, что-то вроде этого:
[javascript]
OpDataset.GotoNext();
[/javascript]
[javascript]
OppDataset.Close();
OppDataset.Open();
[/javascript]
пс: могу предложить не передавать никаких датасетов (т..к скорее всего вы где-то там запутались), а передать сразу нужные значения, которые вы собираетесь использовать, в функцию записи данных в БД. Что-то вроде:
[javascript]
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);
}
[/javascript]
"Олейник Дмитрий" написал:а вот с третьей непонятно. Самое интересное то, что вы ей передаете датасет реестра (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);
}С уважением,
Олейник Дмитрий
Манипуляции выполняются в этом цикле:
[javascript]
//Вот в этом цикле пишутся данные в БД.
for(Dataset.GotoFirst(), Counter = 0; ( !Dataset.IsEOF ); Counter++, Dataset.GotoNext()) {
.....
Dataset.Edit();
.....
}
Dataset.Close();
}
[/javascript]
Сначала выполняется текущая активная строка грида с Stop=0(null), а затем в этом цикле выполняется OLD строка (с Stop=1), которую вроде бы как мы покинули здесь:
[javascript]
if (!IsZeroValue(Stop)) {
MessageBox('Стоит галка Stop ! Ничего в базу не пишем!');
return false;
}
[/javascript]
Напрямую передавать параметры не получится, т.к. они вычисляются и связаны с другими ds.
Можно ли очистить наш OpDataset вообще как-нибудь, что-бы там не было никаких строк old?
И если можно, то в этом месте
[javascript]
if (!IsZeroValue(Stop)) {
MessageBox('Стоит галка Stop ! Ничего в базу не пишем!');
// Здесь очищаем наш дата сет от нашей строки, которая попала сюда.
return false;
}
[/javascript]
Думаю, Вам стоит передать обезличенную копию БД или сервисы в поддержку. Без этого долго воспроизводить придется.