Да лана. Не нужна ему именно 30-я, но хочется быть спозиционированным _примерно_ в то место курсора где был. Вполне законное желание. А тут - хоть циклом по RecNo, хоть букмаркой (которая вообще-то делает то же самое, потому валидна почти всегда, невалидна только если курсор укоротился настолько, что она кажет за его пределы). Это после делета. Апдейты-инсёрты через RefreshSQL обычно рефрешатся, без переоткрытия (хотя есть и постановки, требующие фуллрефреша).Ivan_Pisarevsky писал(а):ЗАЧЕМ??? юзеру 30-я запись???Марина писал(а):Т.е. теперь курсор надо поставить на 30-ю запись!
Как ПРАВИЛЬНО ловить курсор в табл. после передер. сервера?
Определить, где это "примерно" можно только в очень конкретном случае, опираясь на текущие сортировочные поля, если такие есть. Понятие "соседние" зависят от очень разных параметров.Merlin писал(а):Да лана. Не нужна ему именно 30-я, но хочется быть спозиционированным _примерно_ в то место курсора где был.
Разумеется. Если за время редатирования интенсивность вставок-удалений больше экрана, то говорить не об чем. Но даже в этом случае если в курсоре, скажем, около 1000 записей и юзер жевал 600-ю, то, как правило, ему после этого ближе отмахивать к следующей интересующей примерно от середины, чем от начала.WildSery писал(а):Определить, где это "примерно" можно только в очень конкретном случае, опираясь на текущие сортировочные поля, если такие есть. Понятие "соседние" зависят от очень разных параметров.
Правда? Ну, спасибо, просветил. Пример раз. Ценовые группы номенклатора. Главный фильтр - starting. А он не помнит точно на что оно стартинг, особенно когда оно не по-русски стартинг. А в чухонском языке, например, буквица пишется "Y", а читается "Ю". Не, дополнительные фильтры есть конечно - типа с наличием на складах такой-сякой линии поставки, с отклонением усреднённой себестоимости в границах диапазона на такой-сякой линии поставки, с наличием в производственных заказах, с себестоимостью в диапазоне, уценка-нет, валюта закупки, собственное производство-перепродаваемый товар-сырьё для производства, применяемая схема ценообразования и ряд её параметров... И когда босс занимается аналитикой, он иной раз чешет репу и ими и пользуется. А человек, работающий со списком постоянно, быстрей эту несчастную тыщу колёсиком мыша прокрутит и среагирует на семафорную подсветку в том или ином столбце. Это ж не десятки тыщ, а всего лишь тыща. Пример два - тованый состав одной ценовой группы. Есть такие, в которых по одному товару, а есть и по тыще. Что, тоже мурыжить его всегда входом через фильтр-форму? Ой спасибо он тебе скажет... Таких примеров я тебе тыщу могу привести. Вот если таким манером крутят многотысячный товарный номенклатор целиком, да ещё по мудему - оно конешно.WildSery писал(а):такой грид не имеет права на существование, т.к. пользователь сразу перегрузится информацией. Только с неотключаемыми фильтрами, даже если "надо" такое.Merlin писал(а):...около 1000 записей и юзер жевал 600-ю...
Во всех твоих примерах нет непосредственной работы с объектами - редактирования, добавления, удаления. Фактически, это у тебя динамический отчёт. Если же хочешь именно оперировать такими объёмами объектов - стоит подумать, возможно, что ты сам не знаешь, чего хочешь, и пытаешься решить это таким способом.
Я плачу, я просто плачу Человек меряет все задачи на СУБД исключительно редактированием состава накладной, ну ладно, хрен с ним, даже с проходом через список заголовков накладных, и обвиняет меня, у которого в поcледней действующей системе сумма объёма 21 непересекающейся функциональности ехешника, написанных в разных технологиях и под разные платформы, как OLTP, так и OLAP, работающих с одной базой из сотни точек на пространстве от Минска и Хельсинки до Владивостока, включая новые азиатские страны, давно перевалил за сотню мегов, в узости кругозора Мил человек, ну не бывает чиста черного и чиста белого, панимаш, не-бы-ва-ет
С каких это пор команда Open переоткрывает набор? Там тогда перед Open Close должен стоять...Rambos писал(а):Всмысле не открываем а переоткрываем (обновляем)
Подразумевается что до обновления набор был открыт
Народ, предлагаю прекратить разговоры о необходимости вывода сотни/тысячи/десяти тысяч строк. Ситуации бывают разные.
Давайте без Фрейда. Признаю, в Минске и Хельсинки нашего филиала пока нет. Автор обсуждала именно _редактирование_ набора данных. Фразу про накладные - не догнал.Merlin писал(а):...и обвиняет меня, у которого в поcледней действующей системе...
По теме. В данном случае больше всего пользы вижу в FIB'овском ReopenLocate с правильно подобранными полями.
МММ, можно, конечно редактору делать холостой апдейт и занять запись, если он первый в нее залез, либо получить сообщение, что такой записи нет, если запись уже была удалена. Но это чревато тем, что редактор начав изменение записи пожет покурить пойти, а все остальные в это время конфликт транзакций получат.Марина писал(а):Всем привет!
Проблема такая. Я использую компоненты IBQuery, IBUpdateSQL, DataSource. Узменения в таблице произошли, транзакция подтвердилась, сервер передернули с клиента. У меня пользователь сидит в табличке или во вьюшке скажем где-то в середине - редактирует запись, т.е. впереди 100 записей, он редактирует 101-ю и сзади тоже 100 записей (всего в таблице 200 записей). Пока он ее редактировал, другой пользователь удалил его запись и еще 70 записей вперед. Т.е. теперь курсор надо поставить на 30-ю запись! Вопрос в том как ПРАВИЛЬНО это сделать! Помогите пожалуйста! )))
при подобных массовых удалениях как может редактор заранее знать, сколько записей будет удалено? Другой (другие) могут удалить и не 70 записей, а 170.
Re: Как ПРАВИЛЬНО ловить курсор в табл. после передер. серве
Марина писал(а):Помогите пожалуйста!
Удаляю или сохраняю запись в табличке, данные обновляются с сервера, курсор становится на 1-ю запись. Есть способы как это сделать. Вопрос в том, как ПРАВИЛЬНО это сделать, что лучше!
Код: Выделить всё
unit IBQueryA;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, IBCustomDataSet, IBQuery;
type
TIBQueryA = class(TIBQuery)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
procedure TableRefresh(const KeyParams: string ='');
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('InterBase', [TIBQueryA]);
end;
procedure TIBQueryA.TableRefresh(const KeyParams: string ='');
var y:TStrings;
i,xpos:integer;
Par,FirstPar:Variant;
LongVar,Stop,SetSeek:boolean;
bsc,asc:TDataSetNotifyEvent;
procedure SetFieldName;
var i:integer;
begin
for i:=0 to FieldList.Count-1 do
begin
if not Fields[i].IsNull then
y.Add(FieldList[i].FullName);
end;
end;
procedure SetFieldValue;
var i:integer;
begin
LongVar:=false; {Variant is long?}
if y.count>0 then
begin
FirstPar:=FieldByName(y[0]).Value;{First value}
if y.count>1 then
begin
LongVar:=true;
Par:=VarArrayCreate([0,y.count-1{Del first value}], varVariant);
for i:=1 to y.count-1 do {Push other values}
Par[i-1]:=FieldByName(y[i]).Value;
end;
end;
SetSeek:=y.Count>0;
end;
procedure SetSeekParams;
begin
SetFieldName;
SetFieldValue;
end;
begin
SetSeek:=false;
y:=TStringList.Create;
try
if Active then
begin
if Trim(KeyParams)='' then
SetSeekParams
else
begin
xPos := 1;
while xPos <= Length(KeyParams) do
Y.Add(ExtractFieldName(KeyParams, xPos));
SetFieldValue;
end;
{execute BeforeScroll}
if Assigned(BeforeScroll) then BeforeScroll(Self);
end;
DisableControls;
{Hide BeforeScroll,AfterScroll}
bsc :=BeforeScroll;
asc :=AfterScroll;
BeforeScroll := Nil;
AfterScroll := Nil;
{Requery}
if Active then ReQuery else Open;
If SetSeek then begin
Stop:=false;
while not Stop do begin
while not Eof and
(FieldByName(y[0]).asVariant<FirstPar) do Next;
if Variant(FieldByName(y[0]).Value)=FirstPar then begin
{Yes, seek first}
Stop:=true;
If LongVar then {Seek other}
for i:=1 to y.Count-1 do
if Variant(FieldByName(y[i]).value)<>
Par[i-1] then begin
Stop:=false;
Break;
end;
end;
if not Stop then begin
Next;
If Eof then Stop:=true;
end;
end;
end;
{execute AfterScroll}
if Assigned(Asc) then Asc(Self);
{Pop old pointers}
BeforeScroll := bsc;
AfterScroll := asc;
EnableControls;
finally
y.free;
end;
end;
end.
Там все просто - находим параметры (значения полей - достаточно id) для поиска требуемой записи, корректно исполняются AfterScroll and BeforeScroll, затем они = nil - чтоб не отрабатывали при поиске записи.Марина писал(а):Интересный код.... так просто фиг въедешь )))
Спасибо ребята, выйду из отпуска попробую с этим курсором чего-нибудь замутить... ))))
Применение
Код: Выделить всё
taData.Post;
taData.TableRefresh('id');
http://www.ibase.ru/conf.htm надо зарегистрироваться на гугле и гмане.Фанис писал(а): Да я как все - пару недель тыкался в news.demo.ru и ... отпал.