Форум: "Базы";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизТочное позиционирование в DBGrid Найти похожие ветки
← →
msguns © (2005-05-19 17:03) [0]Суть проблемы в том, чтобы после изменения записи в таблице и переоткрытия отображающего ее нередактируемого НД не просто найти эту запись и сделать ее активной, а добиться того, чтобы она отображалась в том же самом месте грида.
Понимаю, что надо поиграться с предком грида, имеющем соотв.св-ва (Row), но это требует массу времени, которого, как всегда, не хватает.
Возможно, у кого-то есть хорошие (не громоздкие) решения, которыми не жаль поделиться. Сделайте одолжение - буду весьма признателен.
← →
DSKalugin © (2005-05-19 17:14) [1]база то какая, а компоненты доступа?
Новые записи как правило добавляются вконец
← →
DSKalugin © (2005-05-19 17:18) [2]поиграйся с TBookmark лучше
в хэлпе есть примеры по использованию
← →
Bronco © (2005-05-19 17:21) [3]
> msguns © (19.05.05 17:03)
Ты имеешь ввиду смещение картинки в гриде после позиционирования на измененой записи?
Тут уже бились над этой проблемой.
На моей памяти решения со стандартным гридом так и не нашли.
По-моему проще организовать рефреш отдельной записи в датасете или же не делать close-open
← →
msguns © (2005-05-19 17:26) [4]>DSKalugin © (19.05.05 17:18) [2]
>поиграйся с TBookmark лучше
Внимательней почитай сабж, я ж не зря подробно написал.
>Bronco © (19.05.05 17:21) [3]
Да, так точно тов.майор !
Только я не верю, что нет решения. Через предка его (решения) не может не быть.
← →
msguns © (2005-05-19 17:32) [5]Кстати, я вот не понял, почему вопрос выкинули из основной, ведь его суть вовсе не в базах данных, а чисто ооповская : как оптимально использовать "зов предков" для придания потомкам большей функциональности.
ИМХО, необъективное решение, вызванное нежеланием вникнуть в смысл сабжа.
Последствия таковы, что проблема останется вне поля зрения таких монстров, как VMcl или ЮЗ, которые в "Базы" наведываются нечасто.
Грустно, бабоньки ;((
← →
Bronco © (2005-05-19 17:39) [6]
> msguns © (19.05.05 17:32) [5]
> я вот не понял, почему вопрос выкинули из основной
Видимо потому что грид - он DB :-)
Кстати, если это так уж мешает сдвиг картинки, то все-таки искренне советую отойти от метода Close-Open, с последующим позиционированием и копнуть в сторону рефреша отдельной записи в DataSet"e
← →
Johnmen © (2005-05-19 17:43) [7]>msguns © (19.05.05 17:03)
Есть сырцы этого дела.
Кому-то когда-то давал. Говорили, что работает. Основания не верить нет. Сам не проверял.
← →
DSKalugin © (2005-05-19 18:04) [8]refreshSQL не помогает?
← →
Polevi © (2005-05-19 18:52) [9]close open в топку
см [6]
← →
msguns © (2005-05-20 09:22) [10]>DSKalugin © (19.05.05 18:04) [8]
>refreshSQL не помогает?
>Polevi © (19.05.05 18:52) [9]
>close open в топку
>см [6]
Вся мулька в том, что технология не должна зависеть от формата БД и используемых механизмов доступа. Проще всего "стать ногами на таблицу", например TTable, и редактировать средствами эитого класса, однако это не решение.
Во-первых потому, что не парадокс/дбэйз
Во-вторых, потому что НД может быть выбран из нескольких таблиц либо может возвращаться ХП, т.е. изначально сам по себе не редактируемый
В-третьих, нельзя ориаентироваться на конкретику в св-ве грида Datasource.Dataset, грид должен уметь это делать сам по себе.
Смысл в том, что хочется иметь 2 функции
Первая воззвращает относительный номер строки текущей активной строки грида,
Вторая - перерисовывает грид так, чтобы строка, относительный номер который представлен на входе одним параметром, перерисовывалась так, чтобы она имела относительный номер, представленный вторым параметром. Возвращает true, если перерисовка удалась либо false, если нет (например, кол-во записей в НД стало меньше после переоткрытия)
Вопрос не так уж и празден, как может показаться с первого взгляда.
← →
Polevi © (2005-05-20 09:36) [11]чушь какаято, имхо
← →
evvcom © (2005-05-20 09:48) [12]Ну изменил запись, ну вызвал метод типа ApplyUpdates, а НД зачем переоткрывать? Если для того, чтобы вернуть с сервера какие-то вычисляемые параметры, генерируемые на сервере ключи например, то для этого есть OUT-параметры. Непонятна проблема.
← →
Виталий Панасенко (2005-05-20 10:02) [13]Может, глянь на VisibleRowCount/TopRow в Grids.pas - предке DBGrid
← →
msguns © (2005-05-20 11:05) [14]>evvcom © (20.05.05 09:48) [12]
НД не редактируемый !
Если же я сделаю его редактируемым, то
1. способы делания нередактируемого НД редактируемым у разных "движков" разные
2. запись после вставки в грид и Apply окажется внизу, т.е. не будет следовать заданной для всего рекордсета последовательностью.
По-моему я достаточно подробно описал суть проблемы, чтобы понять то, ЧТО нужно. Советы типа Polevi, как, впрочем, и комментарии в этом духе, прошу не давать.
Если проблема кажется надуманной - выразите возмущение, но в душе, ладненько ?
Основная цель - разобраться с гридом, а не с средствами доступа. Именно поэтому вопрос изначально был помещен в "Основную".
← →
Johnmen © (2005-05-20 11:31) [15]>msguns © (20.05.05 11:05) [14]
Серёга, я так и не понял, тебе сырцы нужны или ты уже решил проблему ?
← →
msguns © (2005-05-20 11:35) [16]>Johnmen © (20.05.05 11:31) [15]
>Серёга, я так и не понял, тебе сырцы нужны или ты уже решил проблему ?
Нет, не решил, конечно.
Сырцами ты помахал, как ворона перед лисой, и улетел. Где они ?
← →
Johnmen © (2005-05-20 11:39) [17]>msguns © (20.05.05 11:35) [16]
Дык это, щас вышлю, если не возражаешь...:)
← →
msguns © (2005-05-20 11:44) [18]>Johnmen © (20.05.05 11:39) [17]
>Дык это, щас вышлю, если не возражаешь...:)
Наливай !
← →
ЮЮ © (2005-05-20 11:52) [19]>запись после вставки в грид и Apply окажется внизу, т.е. не будет следовать заданной для всего рекордсета последовательностью.
А если после вставки записи внизу и переоткрытия запись должна быть уже вверху, то о каком "точное позиционировании в DBGridе" идет речь? Т.е. пользователь должен остаться внизу грида, недоумевая куда улетела только что вставленная запись и не повторить ли ему ввод, полагая, что это глюк программы ?
← →
Max Zyuzin © (2005-05-20 11:54) [20]>ЮЮ © (20.05.05 11:52) [19]
На скока я понял речь не про вставку а про редактирование, что бы в исходном гриде строчки не скакакли.
>Johnmen © (20.05.05 11:39) [17]
Жень, пришли мне, посмотреть хоцца.
← →
msguns © (2005-05-20 11:56) [21]>ЮЮ © (20.05.05 11:52) [19]
Юр, ну чего ты придираешься. Да, при вставке будет фигня, если узер нажмет мышку, стоя на записи "Иванов", введет "Яковлев" и получит выброс курсора совсем в другое место после переоткрытия.
Но ведь он может (и часто так и делает) ввести "Ковалев".
Но, как правило, речь идет об удалении и редактировании, когда курсор должен оставаться в том же самом месте грида (пример хороший - TTable)
← →
msguns © (2005-05-20 12:08) [22]Спасибо, Жень, получил бандерольку ;)
При первом взгляде не очень красиво (в смысле громоздко, но, возможно, проще и не сделаешь).
Однако в целом похоже на то.
Буду пробовать.
Еще раз спасибо.
← →
evvcom © (2005-05-20 12:17) [23]
> msguns © (20.05.05 11:05) [14]
> >evvcom © (20.05.05 09:48) [12]
>
> НД не редактируемый !
> Если же я сделаю его редактируемым, то
> 1. способы делания нередактируемого НД редактируемым у разных
> "движков" разные
Может я чего не понимаю в твоих терминах, но если набор не редактируемый, то он не редактируемый! Если к TQuery или TStoredProc, которые по сути являются не редактируемыми, прицепляешь UpdateObject, то они уже редактируемы. И способы зависят не от движка БД, а от реализации компонента (класса). И грид воспринимает эти DataSet-ы как редактируемые. И Open/Close делать, я все же не вижу смысла.
> 2. запись после вставки в грид и Apply окажется внизу, т.е.
> не будет следовать заданной для всего рекордсета последовательностью.
И не надо. См ЮЮ © (20.05.05 11:52) [19]. А чтобы привести в порядок последовательность, добавляешь кнопку refresh и используешь TBookmark, и юзер сам решит, когда ему приводить набор в порядок. Выигрыш от этого хотя бы даже в том, что не будет после каждой вставки/апдейта SQL запрос опять лопатить кучу таблиц, нагружать сеть и прочее.
← →
ЮЮ © (2005-05-20 12:18) [24]Это не придирки а непонимание :)
Как раз для редактирования и удаления нет ничего проще, чем сделать редактируемым DataSet, тогда что пользователь сделал в гриде, то и получил, а на сервер пойдет один UPDATE или DELETE.
Если уж переоткрытие так мило, говорят, отключение DataSource у грида (или DataSeta у DataSource) спасает грид от ухода с места.
Еще вариант: перед открытием запомнить первую, последнюю и текущую записи в гриде (ч/з DataLink) и позиционироваться сначала в последнюю, затем в первую и наконец, в последнюю очередь, в текущую, что должно, по идее установить в DataLink теже записи, что и перед переоткрытием
← →
msguns © (2005-05-20 12:51) [25]>evvcom © (20.05.05 12:17) [23]
>Может я чего не понимаю в твоих терминах, но если набор не редактируемый, то он не редактируемый!
Дело не в терминах и вообще не в наборах данных, а в гриде !
Гриду уьтрамариново, редактируемый или нередактируемый датасет он малюет. Что касается всяких UpdateObject, UpdateSQL, Insert/Delete/UpdateSQL и т.д., - то все это разные примочки разных механизмов доступа, позволяющих редактирование собственно в гриде. Но где я спрашивал о том, КАК МОЖНО РЕДАКТИРОВАТЬ В ГРИДЕ ? ГДЕ ???
Вместо того, чтобы пообсуждать проблему ремонта старого телевизора мне упорно советуют купить новый. У меня уже есть новый ! Даже несколько !
Но мне хочется разобраться со старым
Поэтому я пошел не в магазин (БД), а в рем.мастерскую (Общая), откуда меня послали к умникам вроде Polevi
>А чтобы привести в порядок последовательность, добавляешь кнопку refresh
Сам пробовал ? Прежде чем советовать ?
>и юзер сам решит, когда ему приводить набор в порядок
Ага, деваха добавила запись и фиг увидела ее в решетке, добавила другую - тот же отлуп. А потом вспомнила "Ага ! Мне ж надо рефреш нажать" *Что, кстати, ни к чему другому не приведет, поэтому-то нужно переоткрытие.
Во избежание дальнейшего топтания на одном месте уточняю, что речь идет о технологиях типа "читаем в одной транзакции - пишем в другой".
Правда, к гриду опять же это никакого отношения не имеет.
>ЮЮ © (20.05.05 12:18) [24]
>Это не придирки а непонимание :)
Как раз для редактирования и удаления нет ничего проще, чем сделать редактируемым DataSet, тогда что пользователь сделал в гриде, то и получил, а на сервер пойдет один UPDATE или DELETE.
Нет, не годится. Читай выше о транзакциях.
>Если уж переоткрытие так мило, говорят, отключение DataSource у грида (или DataSeta у DataSource) спасает грид от ухода с места.
не спасает.
>Еще вариант: перед открытием запомнить первую, последнюю и текущую записи в гриде (ч/з DataLink) и позиционироваться сначала в последнюю, затем в первую и наконец, в последнюю очередь, в текущую, что должно, по идее установить в DataLink теже записи, что и перед переоткрытием
Вариант Johnmen`а, присланный мне, построен похоже (другого я и не знаю). За идею спасибо. Еще покручу его в котелке ;)
← →
msguns © (2005-05-20 12:56) [26]За эту фразу:
Поэтому я пошел не в магазин (БД), а в рем.мастерскую (Общая), откуда меня послали к умникам вроде Polevi
прошу прощения,- не сдержался.
терпеть не могу хамства, а еще больше - себя хамящего.
← →
evvcom © (2005-05-20 13:03) [27]
> >А чтобы привести в порядок последовательность, добавляешь
> кнопку refresh
>
> Сам пробовал ? Прежде чем советовать ?
Именно так и делаю. Отлично работает.
> Гриду уьтрамариново, редактируемый или нередактируемый датасет
> он малюет
> >и юзер сам решит, когда ему приводить набор в порядок
>
> Ага, деваха добавила запись и фиг увидела ее в решетке,
> добавила другую - тот же отлуп.
Какой он малюет естественно уьтрамариново, но при операциях "редактирования в гриде" грид ведет себя уже не уьтрамариново. И деваха, добавляя запись, нормально видит ее в решетке. Если решетка DB, то автоматом, если не DB, то извини, если ты ей шыш нарисуешь, то его она и увидит.
Может ты не хочешь понять, о чем тебе твердят, либо не можешь толком сформулировать причины не желания использовать более простых и надежных способов. Но я не понимаю, что тебе не нравится в моих советах.
← →
evvcom © (2005-05-20 13:11) [28]
> "читаем в одной транзакции - пишем в другой".
> Правда, к гриду опять же это никакого отношения не имеет.
Вот именно. Грид читает в одной. Далее спрашивает у DataSet редактируемый ли он? Если нет, то не заставишь грид редактировать, если да, то гриду пофиг в действительности вставится запись или нет в транзакции на запись. Он ее отобразит и будет думать, что вставилась. Причем если сделать CancelUpdates, грид должен из своих строк также удалить эти записи. И все это работает (во всяком случае в DevExpress). Могут быть какие-то глюки, но это уже другое, это уже ошибки компонента.
← →
msguns © (2005-05-20 13:22) [29]>evvcom © (20.05.05 13:03) [27]
>Но я не понимаю, что тебе не нравится в моих советах.
Твои советы правильные. Но только в том случае, если редактирование в гриде. Но, поверь, это не единственная и далеко не самая универсальная технология. Не буду здесь доказывать почему иногда невозможно сделать нормальный интерфейс внесения в БД изменений а гриде - не об том речь.
Но вот по поводу рефреша..
Ситуация:
Одна транзакция читает данные с сервера, которые отображаются на клиенте (в том числе в гридах) комплексно. Например: сложный документ с несколькими дочерними таблицами и кучей подсчитанных итогов. Юзер вносит изменение в дочернюю таблицу и надо не просто увидеть изменение в ней, но и пересчитать итоги, отразить изменение в мастер-таблице (например, сумму по фактуре) и т.д. Цепочка может быть достаточно длинной. Поэтому приходится переоткрывать ВСЕ открытые на форме НД. Или большинство из них. Причем изменение в доч.таблице выполняется в другой транзакции, вот почему простой рефреш не "увидит" изменений, т.к. лишь извлекает записи из буфера текущего НД, а он и не менялся однако !
То, что ты говоришь - верно для простых случаев, особенно для локалок с однотабличными объектами (типа справочника или перечня чего-то), но не применимо или сложно применимо, если приходится ориентироваться на многопользовательские технологии, где актуальны вопросы коллизий и "прозрачности" изменений.
← →
evvcom © (2005-05-20 14:54) [30]
> Но только в том случае, если редактирование в гриде.
Не обязательно. Я сейчас делаю проект Delphi/Oracle. Таблиц море, доступ только через хранимки чтение отдельно, запись отдельно. Отображение в гриде, запись через дополнительную форму и DB-компоненты (иногда даже через обычные ComboBox и прочее). Если мне надо пересчитать итог в главном наборе после изменения подчиненного, то хранимка на Update в out параметре может вернуть нужный итог, после чего его можно заменить в главном наборе без переоткрытия и даже искусственно запретить в этом случае вызов хранимки на Update главного набора.
Сделать можно как угодно, было бы желание. И говорить, что это возможно, а это невозможно, не надо.
Но пользоваться твоим компонентом, работающим так, как ты спрашиваешь, я бы не стал. Накладно очень переоткрывать НД на каждом апдейте. Все имхо.
← →
Polevi © (2005-05-20 15:05) [31]>msguns © (20.05.05 13:22) [29]
мне жаль тебя, ты сам не понимаешь что творишь
тебе люди дело советуют а ты огрызаешься
>Цепочка может быть достаточно длинной.
>Поэтому приходится переоткрывать ВСЕ открытые на форме НД. Или большинство из них
бедные пользователи, несчастный сервер
их ждет очередной монстр
← →
msguns © (2005-05-20 15:31) [32]>Polevi © (20.05.05 15:05) [31]
>мне жаль тебя, ты сам не понимаешь что творишь
В жалости не нуждаюсь, побереги ее. Что творю, как это ни странно, вполне понимаю.
>тебе люди дело советуют а ты огрызаешься
Вот это "дело" :
>Polevi © (19.05.05 18:52) [9]
>close open в топку
>Polevi © (20.05.05 09:36) [11]
>чушь какаято, имхо
?
Спасибо, кушайте сами.
В такой форме советуют не советуют, а стебаются.
Я не утверждаю, что технология перечитки супер, но именно о ней я читал у Вострикова с Ковязиным, а также с многочисленных форумов, и не только по интербэйз. Возможно, переоткрытие требуется не всегда и можно фетчить только измененные записи (правда непонятно, что делать с изменениями конкурентов), но я такой не пользуюсь. Возможно, зря.
Но все же такая форма ответов, ИМХО, говорит только о том, что человек не столько желает помочь, сколько себя показать, не так ли. Собственную крутость.
Выглядит это особенно коряво, когда "советы" не по сути, а около. Это неважно, что не в тему. Главное, что всем видна крутизна. Вместо вопроса по гриду мы сведем все дело к порочности Open-Close НД, в гриде отображаемом.
Что, от этого процент холестерина в крови понижается ? Или адреналинчик прибывает ?
Спасибо за внимание, однако в будущем просьба не утруждаться. Обойдемся как-нибудь без.
← →
Polevi © (2005-05-20 16:05) [33]>msguns © (20.05.05 15:31) [32]
ok
← →
Bronco © (2005-05-20 17:05) [34]> msguns ©
Конечно смотри сам, но я все-таки опять про идеологию...
Одно дело, когда юзер по собственному желанию нажал кнопку "Refresh" - тут требуется полное обновление НД, хочешь ты или нет.
Другое дело, когда юзер (или твоя программа) апдейтит одну запись в таблице и тебе ее просто надо обновить на экране.
Вот в этом случае (ИМХО) только ее и желательно обновлять. При этом (опять же ИМХО) совершенно не обязательно видеть изменения конкурентов, на то у юзера есть кнопка "Refresh"
Хотя это только мое мнение, не претендующее на истину.
← →
mr.IL © (2005-05-20 17:48) [35]Может я немного не в тему, но если гетерогенный запрос писать в локальную табицу, там редактировать на прямую, а потом апдейтить в базу тока измененные записи.
← →
Bronco © (2005-05-20 19:21) [36]
> mr.IL © (20.05.05 17:48) [35]
> Может я немного не в тему
В тему. Но не в эту :-)
← →
P.N.P. © (2005-05-20 21:26) [37]>msguns ©
Пора бы смириться - без своего наследника никак.
Да в принципе и с наследником не так просто будет.
ИМХО конечно :)
← →
mr.IL © (2005-05-21 08:16) [38]Между прочим, если скидывать запрос в локальную таблицу, решаем 2 проблемы. 1.Уменьшаем трафик. 2.Решаем поставленную в теме задачу.
← →
Bronco © (2005-05-21 10:30) [39]
> mr.IL © (21.05.05 08:16) [38]
> Решаем поставленную в теме задачу.
Поясни, каким образом твой вариант избавит msguns-а от смещения картинки в гриде?
← →
mr.IL © (2005-05-21 11:09) [40]Локальную таблицу отдаем на редактирование гридом. Когда грид редактирует связанный с ним ДС напрямую, он не смещается после поста.
← →
Bronco © (2005-05-21 13:02) [41]
> mr.IL © (21.05.05 11:09) [40]
Тогда нафига нужна локальная таблица, напрямую можно и серверную редактировать. Тот же самый Post и никакого смещения.
Речь то идет о другом: автору после редактирования нужно полностью обновить набор данных, т.е. close-open. Он строго придерживается сей идеологии и отходить от нее не хочет.
← →
Alex_S (2005-05-22 14:01) [42]Этот вопрос здесь уже обсуждался (например, в начале января 2005 г. Msguns тогда много отдыхал, числа до 15, как водится в Украине, поэтому и пропустил). Кто-то был недоволен предлагаемым решением, но я его использую. Так что, если это кого-то ещё интересует, то пожалуйста. (С тех пор еще немного подчистил)
Суть задачи следующая. Например, DBGrid показывает записи нередактируемого набора TQuery, запись изменяется через TTable, надо вернуть её в DBGrid так, чтобы она попала в ту же строку после перечитки TQuery.
Предлагаемое решение.
Для удобного вида можно в DBGrid1.Options включить dgRowSelect, чтобы ведялалсь вся строка.
Здесь важно определить, в какой строке (начиная с номера 1) из видимого списка DBGrid находилась редактируемая запись. Для этого предлагается следующая процедура обработки события DBGrid1.OnDrawColumnCell:
{ --- Текущая строка в DBGrid1 ---- }
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if gdSelected in State then
NRow:=(Rect.Top div 21);
{ при перерисовке ячеек DBGrid для выделенной ячейки определяем номер строки NReg - глобальная переменная типа integer;
21 - высота строки. У себя проверьте эту величину.
Для того, чтобы затем случайно она не изменилась в других экранных режимах для формы Form1 задайте свойство Scaled:=false }
end;
А теперь воспользуемся вычисленным номером NRow при перечитке TQuery:
При этом указатель сначала стоит на редактируемой записи (которая вносится в набор данных - Table1.Post)
procedure TForm1.RereadQuery(Sender: TObject);
var k,k0,n: integer;
begin
k:=Query1.Fields.Fields[0].AsInteger;
n:=(DBGrid1.Height div 21) div 2; { номер средней строки в DBgrid1 }
if Query1.RecordCount<n then n:=NRow; { Если записей мало }
DBGrid1.DataSource.DataSet.DisableControls;
Query1.Close; Query1.Open;
Query1.Locate("Code",k,[]);
Query1.MoveBy(n-NRow); { обращаемся к средней строке DBGrid"а }
k0:=Query1.Fields.Fields[0].AsInteger; { запоминаем значение Code этой записи -
в задаче использовался набор данных с первым полем Code типа Autoinc }
Query1.Locate("Code",k0,[]); { устанавливаем указатель на среднюю в DBGrid запись }
Query1.MoveBy(NRow-n); { теперь DBGrid двигаться не будет, устанавливаем указатель на измененную запись }
DBGrid1.DataSource.DataSet.EnableControls; { оживляем DBGrid1 }
DBGrid1.SetFocus; { и передаем ей фокус, если надо }
end;
Здесь я также учёл, что в результате редактирования записи она может оказаться уже на новом месте в наборе данных - по условиям сортировки и проч.
Поле Code здесь уникальное, поэтому запись все равно будет однозначно определена. Если кому-то покажется, что где-то
действия Locate и MoveBy лишние, то попробуйте сократить - мне кажется, они несколько по-разному работают с DBGrid.
PS. Не говорю, что решение единственно верное, но ничего лучшего для поставленной цели я пока не придумал. Сделаете лучше, флаг вам в руки. Стрелять пианиста не надо, он играет, как умеет.
С уважением, Alex_S
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.047 c