Delphi 2009 - набор клиентских данных findnearest

У меня проблема с clientdataset и findnearest методом.

Я показываю несколько записей в dbgrid и использую щелчок по заголовку для изменения индекса и сортировки сетки. Я также могу щелкнуть столбец второй раз, чтобы изменить сортировку столбца с восходящей на нисходящую. Кроме того, после того, как я щелкнул столбец, у меня появилось поле Tedit, в котором пользователь может вводить данные, а программа использует метод findnearest для поиска ближайшего совпадения в столбце, который был нажат. Это делается для индексов по возрастанию или по убыванию.

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

Вот некоторые данные, один набор данных в порядке возрастания, другой - в порядке убывания.

По возрастанию - Эйбл, Арнольд, Арни, Барни, Бубба

По убыванию - Бубба, Барни, Арни, Арнольд, Эйбл

Когда я ищу "A" по возрастанию, указатель записи останавливается на Able. Когда я ищу "B" по убыванию, указатель записи останавливается на Арни. Мои два примера не являются теорией, это то, что происходит на самом деле.

Мои вопросы - почему в порядке убывания пропускаются Бубба и Барни? Пожалуйста, не приводите мне другого примера. Воспользуйтесь моими данными, если собираетесь привести пример. Пожалуйста, объясните, почему findnearst пропускает первые две записи в убывающей последовательности, которые явно начинаются с буквы «B».


person Owen    schedule 07.01.2014    source источник
comment
Ответ не изменится, сколько бы раз вы ни меняли образцы данных. То же самое независимо от того, используете ли вы A, B, C или D, E, F, W, Y, Z или Fred, Barney, and Wilma. Это одна и та же проблема и один и тот же ответ, как бы вы ни задавались. Я объяснил это, используя ваши данные, и вместо того, чтобы на самом деле читать то, что я написал (несколько раз), вы просто изменили данные, чтобы задать вопрос.   -  person Ken White    schedule 11.01.2014
comment
@Owen - Это действительно просто: в порядке убывания «B» больше, чем «Bubba» и «Barney». Вот почему B пропускает Bubba.   -  person Sertac Akyuz    schedule 11.01.2014
comment
Спасибо, Сертак, но разве Би не меньше Буббы? Почему, когда я смотрю, Бу падает на Арни?   -  person Owen    schedule 12.01.2014
comment
@Owen - Нет, «Б» не меньше «Бубба». Подумайте об этом с другой стороны: «Бу» меньше «Бубба» в порядке возрастания. Следовательно, обратное должно быть верно в порядке убывания.   -  person Sertac Akyuz    schedule 12.01.2014


Ответы (3)


Я могу объяснить, почему это так (надеюсь, с некоторой ясностью) и почему это действительно правильное поведение. (В следующем описании для простоты просто обсуждаются однобайтовые символы, но ответ должен относиться и к другим.)

Учитывая следующие данные (я намеренно немного изменил их для упрощения объяснения - я надеюсь, вы увидите, почему ниже), давайте предположим, что мы находимся в верхней строке (A для возрастающего порядка, и Чарли для убывания) в обоих случаях.

(Ascending)         (Descending)
LastName            LastName
========            ========
A                   Charlie
Abe                 Bob
Ada                 Ada
B                   Abe
Bob                 A

Начиная с первой строки (строка A) в порядке возрастания и выполняя поиск по запросу Ac, мы сначала встретим Abe. Это не совпадение, и то, что мы ищем, должно быть после него в порядке возрастания, поэтому мы продолжаем поиск Ac.

Его там нет, и теперь мы находимся в строке, в которой было бы найдено совпадение, а именно в строке сразу после нее (Ada). Другими словами, мы располагаемся в том месте, где могло бы быть совпадение, если бы оно присутствовало (ближайшая строка).

Теперь предположим, что мы ищем Al. Мы находимся на Ada, поэтому переходим к следующей строке и обнаруживаем, что Al отсутствует. Сейчас мы находимся в B, где мог бы быть найден Al, если бы он присутствовал. Другими словами, мы находимся в ближайшем ряду. (Это можно подтвердить быстрым тестом.)

В порядке убывания примеры работают точно так же. (Помните, я немного изменил данные, чтобы было легче объяснить.) Давайте поищем Сесил:

Мы находимся в первой строке, Чарли, и переходим к следующей строке в поисках Ce (который будет после Charlie < / strong> в порядке убывания, но не раньше, как показано Abe и A в данных выше). Мы обнаруживаем, что у нас нет совпадения, и в настоящее время мы находимся в строке Bob, где C был бы найден, если бы он присутствовал. Другими словами, в порядке убывания мы находимся в ближайшей строке, как это работало в примере с возрастанием.

Так что в FindNearest нет проблем. Если вы хотите, чтобы поведение было другим, вы должны реализовать его в своем коде (проверьте, нашли ли вы точное совпадение, и если не переместите на одну строку раньше, если это необходимо, и проверьте, где вы хотите быть вместо).

person Ken White    schedule 08.01.2014
comment
Спасибо за объяснение, оно имеет смысл. Но по убыванию данных мы могли бы иметь: - person Owen; 08.01.2014
comment
Спасибо за объяснение, оно имеет смысл. Но в нисходящих данных у нас могут быть: Charlie, Chirly, Chosey, Cmmar, Bob, Ada, Abe A. И когда я ищу букву C, она будет указывать на Боба. Так что, похоже, он пропускает все C. - person Owen; 08.01.2014
comment
Это правильно. Это не пропускает все C. Смотрите мой ответ, последние три абзаца. Он точно объясняет, что происходит, когда вы ищете только C. C идет после Чарли, чтобы он нашел Чарли, перешел в следующий ряд, ища только C, и не нашел его. Следовательно, мы находимся на ближайшей строке, как я объяснил выше. Точное поведение и его причины указаны в моем ответе, а решение для обхода такого поведения - в последнем абзаце этого ответа. Поведение корректно согласно правилам сортировки (сортировки) символов. - person Ken White; 08.01.2014
comment
Пожалуйста, следуйте точной последовательности, которую я указал дважды (один раз в моем ответе и один раз в моем последнем комментарии). Я объяснил это шаг за шагом в них обоих; Я не уверен, насколько поможет повторение этого в третий раз, но я сделаю это - это будет последний раз, когда я попробую. Он не пропускает все значения "C", потому что отсутствует значение "C". Есть «Чарли», и когда он движется мимо (ниже в сетке) в порядке убывания, «C» нет, но он находится в позиции «C», поэтому он имеет нашел ближайшую строку в порядке убывания - это то место, где она должна быть. - person Ken White; 10.01.2014
comment
Я продолжаю объяснять. Ваше замешательство в этом предложении из вашего вопроса: findnearest выбирает запись перед той, которая должна была быть выбрана .. Нет, это не так, потому что в порядке убывания (C, B, A) , A идет после B, а не перед. Вы даже правильно сказали это как Кошки, Бейкер и Эйбл. (обратите внимание: C, B, A или C идет перед B, что идет перед A). - person Ken White; 10.01.2014

Хорошо, я пойду.

Ваша основная проблема заключается в том, что вы думаете, что FindNearest должен «знать», в каком порядке находятся элементы. То есть поведение, которое вы хотите, - это когда список находится в порядке убывания, вы хотите, чтобы FindNearest начинался с нижней части списка и работал вверх.

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

person Tony Hopkinson    schedule 11.01.2014
comment
Удачи. Я уже сказал об этом: начиная с первой строки (строка A) в порядке возрастания, и мы находимся в первой строке, Чарли, и переходим к следующей строке, ища сила. Надеюсь, тебе повезло больше, чем мне. :-) В удаленном ответе, который он опубликовал, он даже указывает, что понимает поведение в порядке возрастания (если я наберу «ac», он приземлится на baa. Это работает так, как должно.), Но думает, что точно так же поведение в порядке убывания неверно. Я объяснял это по крайней мере шесть раз (три выше и еще три в комментариях, оставленных к пропавшему ответу, все безрезультатно. - person Ken White; 11.01.2014
comment
Подумал, что помогу тебе, когда увидел, что его собственный ответ помечен как не ответ, но это не так. - person Tony Hopkinson; 11.01.2014
comment
Я провел два дня, повторяя одно и то же разными способами, но безуспешно. Я рисовал картинки, использовал слова меньшего размера, использовал другие данные, чтобы попытаться сделать это более понятным ... Все, что у меня было, - это головная боль. Нет, спасибо, нет голосов (от него), нет. Ну, полагаю, я получил «При всем уважении» перед завуалированным оскорблением моего интеллекта. :-) - person Ken White; 11.01.2014
comment
При всем уважении, это красный флаг, означающий, что у указанного человека нет ничего для вас. Это там наверху, я знаю, что это не мое дело, но ... - person Tony Hopkinson; 11.01.2014
comment
Ага. :-) Когда я увидел это, я понял, что ничего не добьюсь (но все равно попробовал еще дважды). :-) - person Ken White; 11.01.2014

В delphi метод findnearest выполняет GotoNearest и GotoNearest согласно документации delphi; помещает курсор на запись, которая является точной записью, указанной текущими значениями ключей в буфере ключей, или первой записью, значения которой превышают указанные.

Это имеет смысл в порядке возрастания, у меня есть две записи AU и BU и поиск B. B больше AU, но меньше BU, поэтому он помещает курсор на первую запись, значения которой превышают указанные - BU.

Но при спуске он работает иначе с точки зрения результата. Если у меня есть две записи BU и AU в убывающей последовательности, и я ищу B, курсор останавливается на AU. Меня это сбивает с толку. BU больше B, так почему бы не приземлиться на BU?

Причина; В документации говорится, что если совпадений нет, курсор будет помещен на первую запись, значение которой превышает указанные. Но на самом деле gotonearest выполняет getnext. Итак, в возрастающем индексе getnext - это больший ключ, но в убывающем индексе getnext - меньший ключ.

person Owen    schedule 13.01.2014
comment
Ваш третий абзац не точен. Вы говорите, что у вас есть две записи «BU» и «AU» последовательно. Таким образом, у вас нет проблем с принятием того факта, что «AU» стоит после «BU» ((больше). Но вы, кажется, не в состоянии принять тот факт, что «B» всегда находится между «AU» и «BU». Если бы у вас была дополнительная запись «B», ваша последовательность была бы «BU», «B», «AU» (вставьте запись и убедитесь сами). Это означает, что "BU" больше "B" неверно, что также делает недействительным в порядке убывания он работает по-другому. - person Sertac Akyuz; 13.01.2014
comment
По другому не работает, работает точно так же. Findnearest ничего не знает об упорядоченности предметов. Это то, что мы все пытаемся донести, и у вас, похоже, есть настоящая проблема. Попробуйте с неупорядоченным списком! - person Tony Hopkinson; 14.01.2014
comment
Сертак, я согласен, что B находится между AU и BU. Восходящая последовательность AU B BU. По убыванию БУ Б АУ. Когда я говорю, что работает по-другому, я имею в виду результат, а не внутренности. Да, внутренний такой же, но результат поиска B в убывающей последовательности по сравнению с возрастающей даст другой результат. Итак, в возрастающем индексе getnext - это больший ключ, но в убывающем индексе getnext - меньший ключ. Результат другой, да, с getnext работает так же. - person Owen; 14.01.2014
comment
Тони, другой результат, а не разные внутренности. Самый близкий из тех, что я использую, знает о порядке. Я использую набор клиентских данных. Мой delphi не позволит мне запустить findnearest, если я не установлю index. Я никогда не видел индекс как неупорядоченный набор. Если найти ближайшие пробеги с неупорядоченным набором - отлично, я этого не делал. Я имею дело с наборами клиентских данных и индексами. - person Owen; 14.01.2014