Форум » [x]Harbour » Сортировка по алфавиту ??? » Ответить

Сортировка по алфавиту ???

Andrey: Всем привет. Постановка задачи такая: Есть справочник-улиц (street.dbf) типа: Kstreet - Street 1 - Махалина ул. 2 - Федорова ул. ..... 990 - Алтуфьевское шоссе ..... В основной базе "списка адресов" (допустим dogovor.dbf) записывается код улицы Kstreet. При выборке из базы (использую условный индекс) выводиться нужный мне список. Задаю сортировку по коду улицы (Kstreet). Получаю отсортированный список не по алфавиту улиц. А как решить вопрос с сортировкой по алфавиту базы (таблицы) "списка адресов" ? Чтобы список показывался по алфавиту ???

Ответов - 57, стр: 1 2 3 All

AlexMyr: Andrey пишет: Задаю сортировку по коду улицы (Kstreet). Получаю отсортированный список не по алфавиту улиц. Индекс ведь по коду, а не по наименованию

Andrey: AlexMyr пишет: Индекс ведь по коду, а не по наименованию Вот именно. А коды не совпадают с (алфавитом) улиц. Пытался делать справочники улиц заранее, но по всем городам не смог. Для печати приходиться делать отдельную базу и выводить туда наименование улиц. Сортировка тогда правильная. Может кто решил данную проблему ? Поделитесь идеей....

Pasha: В dogovor сделать relation на street по kstreet И создать временный индекс по street->Street

Andrey: Pasha пишет: В dogovor сделать relation на street по kstreet Это уже есть давно.... Pasha пишет: И создать временный индекс по street->Street Это тоже есть.... Я про бд-улиц (use street ; index on UPPER(street) to.... ), этот индекс у меня постоянный. Как базу dogovor.dbf индексировать ? Условие сортировки какое ставить ?

AlexMyr: И я о том же, нужен отдельный индекс по street и при выводе на екран переключаться на этот индекс.

AlexMyr: Ага, список выводится из базы dogovor, где есть только kstreet, а из базы street берутся только наименования через relation, правильно понял?

Pasha: Andrey пишет: Это тоже есть.... Я про бд-улиц (use street ; index on UPPER(street) to.... ), этот индекс у меня постоянный. Как базу dogovor.dbf индексировать ? Условие сортировки какое ставить ? В street должен быть управляющий индекс по kstreet, это для того, чтобы работал set relation. А в dogovor сделать индекс по выражению street->Street Но надо иметь в виду, что этот индекс будет работать, только когда включен set relation, иначе его использовать нельзя

Andrey: AlexMyr пишет: И я о том же, нужен отдельный индекс по street и при выводе на екран переключаться на этот индекс. Я не понимаю как переключаться ? Использую условную индексацию: INDEX ON &cIndexTo TAG "ONE" TO (имя врем.индекса) ; EVAL SAY_PROCENT() ; EVERY nKolRecords / 10 WHILE &cFilterTo ADDITIVE cIndexTo := "STR(KCITY)+STR(KSTREET)+UPPER(PADL(ALLTRIM(НОМЕР_ДОМА),5))+STR(НОМЕР_ПОДЪЕЗДА)" cFilterTo := "Kcity=350.AND.!DELETED()" И дальше переключаю на этот индекс.

Andrey: Pasha пишет: В street должен быть управляющий индекс по kstreet, это для того, чтобы работал set relation. Да это уже есть у меня. А в dogovor сделать индекс по выражению street->Street Не совсем понял.... Но надо иметь в виду, что этот индекс будет работать, только когда включен set relation, иначе его использовать нельзя Да это уже есть у меня....

Pasha: Andrey пишет: cIndexTo := "STR(KCITY)+STR(KSTREET)+UPPER(PADL(ALLTRIM(НОМЕР_ДОМА),5))+STR(НОМЕР_ПОДЪЕЗДА)" Вместо KSTREET поставить STREET->STREET и сделать set relation, как я написал

AlexMyr: Andrey Подумал и сделал бы так, основная база street, дочерняя dogovor, дальше основной индекс street и вывод списка street->street, dogovor->field1,dogovor->filedn

Pasha: или не заморачиваться с релэйшн, а написать функцию func StreetName if dogovor->KStreet != street->KStreet street->(dbSeek(dogovor->KStreet)) endif Return street->Street и использовать выражение "STR(KCITY)+StreetName()+UPPER(PADL(ALLTRIM(НОМЕР_ДОМА),5))+STR(НОМЕР_ПОДЪЕЗДА)"

Andrey: AlexMyr, Pasha - СПАСИБО БОЛЬШОЕ !!! Буду пробовать...

Pasha: AlexMyr пишет: Andrey Подумал и сделал бы так, основная база street, дочерняя dogovor, дальше основной индекс street и вывод списка street->street, dogovor->field1,dogovor->filedn Я часто использую такой прием, в комбинации с переопределением навигационных блоков кода. Но, боюсь, это будет слишком нетривиально, навигационные блоки у меня немаленькие.

petr707: Цитата: Задаю сортировку по коду улицы (Kstreet). Получаю отсортированный список не по алфавиту улиц. Иногда в этом случае можно получить и сортировку по алфавиту Если есть возможность применения собственных кодов улиц для связки со справочником, то можно содержать ключи, задающие алфавитную сортировку наименований улиц, число которых конечно (явно ограничено). То есть значение ключа - это некий хэш от названия. Ключа длиной 10 символов достаточно для обеспечения нужной сортировки и уникальности ключа.

Vlad04: Андрей, ты же любитель условной индексации. А с ней просто получается. Создаем временный индекс В базе перед созданием индекса должно быть установлена связь бызы договоров с улицами по коду улиц. Dbsetorder(0) go top IndexTo := "street->STREET+UPPER(PADL(ALLTRIM(НОМЕР_ДОМА),5))+STR(НОМЕР_ПОДЪЕЗДА)" cFilterTo := "Kcity=350.AND.!DELETED()" ORDSETFOCUS( "ONE" ) Паша, выше все написал. Попробовал, все строится как надо.

Andrey: Vlad04 пишет: Паша, выше все написал. Попробовал, все строится как надо. Спасибо. Я тоже уже попробовал. Все классно получается. Чуть-чуть медленей показывается список. А так все здорово.

Andrey: А как получить "УСЛОВИЕ ОТБОРА" - FOR из индекса ? Использую условную индексацию: SELECT MYDBF INDEX ON &cIndexTo TAG "ONE" TO (имя врем.индекса) ; EVAL SAY_PROCENT() ; EVERY nKolRecords / 10 FOR &cFilterTo ADDITIVE cIndexTo := "STR(KCITY)+STR(KSTREET)+UPPER(PADL(ALLTRIM(НОМЕР_ДОМА),5))+STR(НОМЕР_ПОДЪЕЗДА)" cFilterTo := "Kcity=350.AND.!DELETED()" ....... код программы ....... SELECT MYDBF cIndexTo := DBORDERINFO(DBOI_EXPRESSION) ? cIndexTo cFilterTo := ???? Мне нужно получить значение cFilterTo

Andrey: Нашел.... DBORDERINFO(DBOI_CONDITION) ! А как для случая - WHILE ? INDEX ON &cIndexTo TAG "ONE" TO (имя врем.индекса) ; EVAL SAY_PROCENT() ; EVERY nKolRecords / 10 WHILE &cFilterTo ADDITIVE Мне нужно получить значение cFilterTo

Петр: Предложение WHILE не сохраняется в индексном файле

Andrey: Петр пишет: Предложение WHILE не сохраняется в индексном файле Спасибо....

Andrey: Привет всем ! Столкнулся с такой проблемой - в базе есть поле НОМЕР_ДОМА ( С 5,0 ) Допустим список домов "1", "2", "3", "17в", "15", "11" и т.д. При сортировке получаю ерунду 1 11 15 17в 2 3 Как бы правильно отсортировать это поле, чтобы дома правильно стояли ? Можно конечно и через 2 поля (сделать разборку поля НОМЕР_ДОМА) - но не желательно...

Dima: попробуй PADL(твой ключ,длина,"0")

Andrey: Dima пишет: попробуй PADL(твой ключ,длина,"0") А как быть с 17в ? У меня таких домов очень много 58а, 58б, 19а и т.д. .....

Dima: Andrey пишет: А как быть с 17в ? А куда он встал при такой сортировке с padl ?

nick_mi: Я думаю, где-то в 3-х значные номера домов. Очевидно здесь в лоб PADL нельзя использовать. Необходим анализ, если последний символ номера буква - PADL, иначе к номеру в конце добавить пробел, тогда сортировка будет правильная

vvv: index on str(val(dom))+dom красиво отрабатывает, в том числе и штучки типа 10/1, 10-1.

petr707: ..... index on fdom() to test .... Function fdom() Static cifr:='0123456789' return PADL(val(charonly(cifr,dom)),5,'0')+charrem(cifr,dom)

Andrey: vvv пишет: index on str(val(dom))+dom красиво отрабатывает, в том числе и штучки типа 10/1, 10-1. Спасибо БОЛЬШОЕ ! Это самое изящное решение проблемы !

Andrey: vvv пишет: index on str(val(dom))+dom красиво отрабатывает, в том числе и штучки типа 10/1, 10-1. Что-то не правильно сортирует ! 9 11 12 .... 16Б ... 89А .... 97 97К 100 100 100 102Б 102Б 102Б 16 13 13 19/2 19/2 73 11 9Б 11 Как нужно делать тогда ?

Andrey: Пардон, извиняюсь... Все правильно сортирует, там еще улица в сортировке присутствует !

Andrey: Pasha пишет: Вместо KSTREET поставить STREET->STREET и сделать set relation, как я написал От set relation в МиниГуи пришлось отказаться. Поставил спец.функцию показа - Say_Dbf( (cAlias)->KSTREET, "STREET", "STREET" ) Как теперь сделать сортировку столбца/колонки по улице в алфавитном порядке ?

Dima: Andrey пишет: Как теперь сделать сортировку столбца/колонки по улице в алфавитном порядке ? По индексу однако или юзать что то свое в плане set relation , и да МиниГуи тут не при чем Andrey пишет: Поставил спец.функцию показа - Say_Dbf Телепаты уже в пути

Andrey: Dima пишет: юзать что то свое в плане set relation , и да МиниГуи тут не при чем МиниГуи здесь ещё как причем ! Я уже писал об этом: при использовании set relation в Tsbrowse неправильно отображаются записи, при использовании(показе) ДВУХ Tsbrowse. Если убрать set relation то всё отлично. Dima пишет: Телепаты уже в пути Постановка задачи такая: Есть справочник-улиц (street.dbf) типа: Kstreet - Street 1 - Махалина ул. 2 - Федорова ул. ..... 990 - Алтуфьевское шоссе ..... В основной базе "списка адресов" (допустим TEST.dbf) записывается код улицы Kstreet. Создаю индекс по коду улицы (Kstreet) в основной базе. Получаю отсортированный список не по алфавиту улиц, а по коду. Как решить вопрос с сортировкой по алфавиту базы (таблицы) "списка адресов", чтобы список показывался по алфавиту ???

Haz: Andrey пишет: МиниГуи здесь ещё как причем Андрей, минигуи, а именно TSbrows отражает в ячейке то что вернет блок выборки. Тот что по умолчанию у меня терял алиас ( мож сейчас все нормально, давно использую свой) Но то что минигуи не может влиять на работу драйвера баз данных и на его установки по set relation это точно. Так что проблема не в минигуи, а в том что от него просят. Уверен если скормить минигуи свой правильный блок то с реляцией проблем не возникнет По второму вопросу- делай локальный индекс в выражение которого по коду возвращает название улицы, или загоняй массив что нужно и сортируй как хочется или используй SQL и получая склейку через JOIN и ORDER BY показывай уже отсортированно. Самый простой - это по массиву или mem: базе, заполнил проиндексировал и показывай.

Vlad04: Andrey Я делаю так База1 и БАЗА2 СОЕДИнены set relation . Далее создаю индекс, который не должен автоматически открываться ( в другое место его помещаю) В индексное выражение включаю поля Базы2. INDEX ON UPPER(Fam+IM+Ot+dTOS(kLIENT->bIRTH_DATE) ) Tag "ONE" TO (Par1+"TempIndex.cdx") Поля Базы2 показываю в Бровсе1 совместно с полями Базы1. Двух Tsbrowse здесь не должно быть всё Ок

Andrey: Vlad04 пишет: Я делаю так База1 и БАЗА2 СОЕДИнены set relation . НЕ МОГУ делать через set relation !!! Уже писал об этом - глючет показ Tsbrowse в МиниГуи (как исправить не знаю). Нужно найти решение без set relation. Можно сделать вариант с пере открытием базы улиц, но мне это не подходит. Я все базы открываю при запуске задачи.

Vlad04: а пример небольшой ?

Andrey: Vlad04 пишет: а пример небольшой ? Вот пример - https://cloud.mail.ru/public/LrPi/piq8pzAWS Создание индекса делать в util_Use.prg строка 32

Haz: Andrey пишет: Вот пример Ответил в почту

Vlad04: Что-то у тебя со структурой в базе test_main.dbf ?. Поля #1#, #2# странные, не все просмотрщики видят, Far вываливается

Dima: Vlad04 пишет: Что-то у тебя со структурой в базе test_main.dbf ?. Поля #1#, #2# странные, не все просмотрщики видят, Far вываливается У меня Far не упал , а поле обычное "C" длина только 500 байт

Andrey: Vlad04 пишет: Что-то у тебя со структурой в базе test_main.dbf ?. Поля #1#, #2# странные, не все просмотрщики видят, Far вываливается Пользуйся для Харбора viewer'ом - dbedit ! В базу ПЕРВЫМ полем добавить: [pre2]AADD( aDbf , {"ID2" ,"+", 8,0 } )[/pre2] То любой просмоторщик "сдохнет".

Pasha: Вот пример - https://cloud.mail.ru/public/LrPi/piq8pzAWS Создание индекса делать в util_Use.prg строка 32 Данный пример несамодостаточен, а разбирать десятки килобайт чужого кода, чтобы найти там крупицу необходимого, желания нет. Делаем самодостаточный пример с использованием файлов dbf, созданных программой: proc main use test_street new index on kstreet to test_street use test_main new set relation to kstreet into test_street index on test_street->street to test_main browse() retu Запускаем. Видно, что сортировка получается, как заказывали. Замена tbrowse на tsbrowse из hmg испортить результат не может, поскольку и для первого, и во второго источник данных будет один и тот же, и колонки формируются по одному принципу: вызов нужного блока кода.

Andrey: Pasha пишет: Замена tbrowse на tsbrowse из hmg испортить результат не может, поскольку и для первого, и во второго источник данных будет один и тот же, и колонки формируются по одному принципу: вызов нужного блока кода. Позволь не согласиться, результат будет разный. Там особенности показа ДВУХ Tsbrowse в МиниГуи. Можешь сам попробовать и убедиться в этом. Нужно в примере рас комментировать строки: [pre2] //SET RELATION TO KSTREET INTO STREET //cKey := "UPPER(STREET->STREET)" [/pre2] и заменить строку: [pre2] DATA {|| Say_Dbf((cAlias)->KSTREET, "STREET", "STREET", 1 ) } ; // Form_SelDbf.prg на //DATA {|| STREET->STREET } ; // если подключено SET RELATION TO KSTREET INTO STREET в util_Use.prg[/pre2] и пере собрать проект. Если не использовать SET RELATION то показ ДВУХ Tsbrowse - отличный !!! Я пробовал при вызове второго Tsbrowse отключать SET RELATION, но это не помогло. На маленьких примерах в МиниГуи всё проходить отлично, но когда делаешь большие программы, то иногда получаешь совсем не тот результат. Но это скорее всего дело НЕ в МиниГуи, а в незнании/не понимании - как нужно правильно программировать в МиниГуи. Из-за этого и начал я делать большие примеры на МиниГуи, чтобы показать новичкам (да и себе тоже) как НУЖНО делать.

Andrey: Вот что Haz предложил: cKey := "KEY2NAME(KSTREET)" INDEX ON &cKey TO ( PATH_SYS + "test_main6.cdx" ) ADDITIVE DbSetOrder(6) // индекс основной базы по алфавиту справочника ....... Func KEY2NAME(c) STREET->(DBSEEK(c, .F.) ) RETURN STREET->STREET Спасибо ! Кому интересно, вот последний проект - https://cloud.mail.ru/public/BKCu/XGvekDSfe

Dima: Pasha пишет: Запускаем. Видно, что сортировка получается, как заказывали. Паш в терминале так и есть а вот в Минигуи нет , если еще и два бровса , как с этим обстоят дела в FW не знаю.

Pasha: Чтобы не копаться в этих сырцах, можно рассказать в двух словах ? Как я понял, в одном окне живут два бровса. Для первого источник данных - это test_main, и он должен быть отсортирован по test_street->street. А что во втором бровсе, какой у него источник данных ?

Andrey: Pasha пишет: Как я понял, в одном окне живут два бровса. Для первого источник данных - это test_main, и он должен быть отсортирован по test_street->street. А что во втором бровсе, какой у него источник данных ? Не так ! Открывается основная таблица в Tsbrowse. Источник test_main.dbf В этой таблице есть колонка "List of streets" (поле KSTREET) при редактировании вызывается второй Tsbrowse (источник test_street.dbf - уже открытая область базы STREET). Если делать с SET RELATION TO KSTREET INTO STREET, то 1-я запись во втором Tsbrowse "перескакивает" в первый Tsbrowse. Почему - непонятно. Я долго с этим бился. Помогает: 1) пере открытие справочника STREET 2) отказ от SET RELATION

Pasha: Еще раз уточним проблему. При клике на колонку выскакивает модальное окно со 2-м бровсом по test_street, и... ? Неправильно перерисовывается 1-е окно, если 2-е ездит по нему ? Или неправильно перерисовывается 1-е окно после закрытия 2-го ? И еще (дополню). Во 2-м бровсе по test_street часом не изменяется текущий индекс ?

Andrey: Pasha пишет: Еще раз уточним проблему. При клике на колонку выскакивает модальное окно со 2-м бровсом по test_street Да ! Pasha пишет: Неправильно перерисовывается 1-е окно, если 2-е ездит по нему ? Да !

Pasha: Когда 2-й бровс катается по 1-му, в 1-м меняется порядок строк, или неправильно отображается колонка "List of streets" ?

Pasha: Вот что Haz предложил: Так этот вариант работает ? Может я зря копаюсь, и вопрос исчерпан ?

SergKis: Andrey Ты не внимательно читаешь тему (или НЕ). Pasha ишет Отправлено: 05.01.12 16:37. ... или не заморачиваться с релэйшн, а написать функцию func StreetName if dogovor->KStreet != street->KStreet street->(dbSeek(dogovor->KStreet)) endif Return street->Street и использовать выражение "STR(KCITY)+StreetName()+UPPER(PADL(ALLTRIM(НОМЕР_ДОМА),5))+STR(НОМЕР_ПОДЪЕЗДА)"

Vlad04: Типичная ситуация. При открытии второго окна с улицами отменяется SET RELATION, индекс улиц переводится - по ИМЕНИ, после выбора улицы или отказа индекс переводится по коду, восстанавливается SET RELATION.

Dima: Vlad04 пишет: При открытии второго окна с улицами отменяется SET RELATION, индекс улиц переводится - по ИМЕНИ, после выбора улицы или отказа индекс переводится по коду, восстанавливается SET RELATION. Обрати внимание что при этом происходит в первом окне , заскринь его до и после вызова окна два и найди отличия. Мне пришлось для показа окна два , повторно открывать базу улиц с другим Alias (это я условно , задача у меня совсем другая)

Andrey: Pasha пишет: Так этот вариант работает ? Может я зря копаюсь, и вопрос исчерпан ? Да ! Вопрос исчерпан. Просто Haz предложил чуть раньше. Я и сделал его вариант. SergKis пишет: Ты не внимательно читаешь тему (или НЕ). Pasha ишет Да не понял я. Посчитал что Pasha уточняет что происходит с Tsbrowse. Andrey пишет: Кому интересно, вот последний РАБОЧИЙ проект - https://cloud.mail.ru/public/BKCu/XGvekDSfe



полная версия страницы