powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
13 сообщений из 13, страница 1 из 1
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186332
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет!

Такой вопрос, создавая выражение индексу, можно лишь относительно всего выражения
дать сортировку, написав вконце ASCENDING | DESCENDING
А если я складываю в выражение 2 поля, например
INDEX ON DTOS(DATE) + STR(Quantity,7) TAG xXx
но при этом хочу чтобы даты шли с младшей до старшей, а количество с большего до меньшего, такое возможно?
Т.е что-то типа
INDEX ON DTOS(DATE)[DESCENDING] + STR(Quantity,7)[ASCENDING] TAG xXx
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186438
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
INDEX ON DTOS(DATE) + STR( 10 ** 8 -Quantity, 8 ) TAG xXx
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186457
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ
Код: plaintext
INDEX ON DTOS(DATE) + STR( 10 ** 8 -Quantity, 8 ) TAG xXx

Владимир, а вы уверены, что при отрицательных Quantity сортировка по этому полю будет верная?
С уважением, Алексей.
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186497
-=AlexiS=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksey-K - с вашего позволения

Вот функция , взятая на сайте Алексея Климова
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
*-- Обращение значения переменной для обратной сортировки и преобразование ее в символFunction Revers
Lparameters luStr, lnPrecision, lnScale
Do Case
Case Vartype(m.luStr) = "T"
	Return Revers(Ttoc(m.luStr, 1 ))
Case Vartype(m.luStr) == "C"
	m.luStr = Chrtran(Nvl(m.luStr, ""), ["э], [э"])
	Return Chrtran(m.luStr, " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Ёё№АБВГДЕЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьюя", ;
		"яюьыъщшчцхфутсрпонмлкйизжедгвбаЯЮЭЬЫЪЩШЧЦХФУТСРПОНМЛКЙИЗЕДГВБА№ёЁ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#! ")
Case Vartype(m.luStr) == "N" OR Vartype(m.luStr) == "Y"
    IF Vartype(m.luStr) == "Y"
     m.luStr=MTON(m.luStr)
    endif 
	m.lnPrecision = Iif(Vartype(m.lnPrecision)=="N", m.lnPrecision,  18 )
	m.lnScale = Iif(Vartype(m.lnScale)=="N", m.lnScale,  2 )
	Return Revers( NumToStr( m.luStr, m.lnPrecision, m.lnScale ))
Case Vartype(m.luStr) = "D"
	m.luStr = Nvl(m.luStr, {})
	Return  Str( 99999999  - Val(Dtos(m.luStr)))
Otherwise
	Return ""
Endcase
Endfunc

т.е.
Код: plaintext
INDEX ON DTOS(DATE) + Revers(Quantity) TAG xXx

Кстати в догонку : сортировка просто по STR(Quantity,7) - тоже нехорошо
посмотри например что будет в случае если в одной дате будут значения
1
10
100
2
20
200

для того чтобы легче понять

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE CURSOR t1 ( n1 N( 5 . 2 ))
INSERT INTO t1 VALUES ( 1 )
INSERT INTO t1 VALUES ( 10 )
INSERT INTO t1 VALUES ( 100 )
INSERT INTO t1 VALUES ( 2 )
INSERT INTO t1 VALUES ( 20 )
INSERT INTO t1 VALUES ( 200 )
INSERT INTO t1 VALUES (- 1 )
INSERT INTO t1 VALUES (- 10 )
INSERT INTO t1 VALUES (- 100 )
INSERT INTO t1 VALUES (- 2 )
INSERT INTO t1 VALUES (- 20 )
INSERT INTO t1 VALUES (- 200 )
SELECT *,STR(n1, 5 , 2 ) FROM t1 ORDER BY  2 

дабы такого небыло
у того-же Алексея подсмотрена функция
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Function NumToStr
Lparameters luStr, lnPrecision, lnScale

IF Vartype(luStr) == "Y"
     m.luStr=MTON(m.luStr)
endif 

luStr = Nvl(luStr,  0 )
lnPrecision = Iif(Vartype(lnPrecision)=="N", lnPrecision,  18 )
lnScale = Iif(Vartype(lnScale)=="N", lnScale,  2 )
Return Iif(luStr <  0 , 'A', 'Z') + ;
	IIF(luStr <  0 , Str(- 99999999999999 . 99  - luStr,lnPrecision,lnScale), Str(luStr,lnPrecision,lnScale))
Endfunc

для проверки
Код: plaintext
SELECT *,numtoSTR(n1) FROM t1 ORDER BY  2 

т.е.
прямой индекс

Код: plaintext
INDEX ON DTOS(DATE) + numtostr(Quantity) TAG xXx

обратный

Код: plaintext
INDEX ON DTOS(DATE) + Revers(Quantity) TAG xXx
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186754
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-=AlexiS=- Кстати в догонку : сортировка просто по STR(Quantity,7) - тоже нехорошо
посмотри например что будет в случае если в одной дате будут значения
1
10
100
2
20
200

Не так, ведь ведущие пробелы никто не отсекает. Так что, все будет в порядке. Получится такой ряд

______1
______2
_____10
_____20
____100
____200


Приведенный далее пример - некорректен.

Во-первых, автор ничего не говорит ни об отрицательных значениях ни о дробных значения. Поскольку речь идет о количестве (Quantity), то, скорее всего, это все-таки положительные целые значения. Тем более, преобразование STR(...,7) на это и рассчитано.

Во-вторых, Вы превышете допустимую размерность. N(5,2) предполагает, что под целую часть, включая знак , будет отведено только 2 разряда. 5 - всего, 2 - после запятой, 1 - разделитель, Целая часть = 5-2-1=2 разряда

Поэтому как числа 100, так и числа -100 - это превышение допустимой размерости. То, что FoxPro позволил ввести такое значение - это особенность способа физического хранения полей типа Numeric. Но логически - это ошибка.

В-третьих, ошибка связана не только со знаком, но и с некорректным указанием размерности в функции STR(). Ведь, по сути, хотя Вы и заявили размерность N(5,2), но фактически ввели значения типа N(7,2). Т.е. необходимо, как минимум, преобразование типа STR(...,7,2).

Ну, и знак, конечно, влияет, про который в условии вообще ничего не говорится.
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186938
-=AlexiS=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to ВладимирМ
Вы конечно правы
Но я писал свой пост до того как увидел ваши Алексея, что так получилось (мой сразу за его ) - просто совпадение.
Функции привел для "общего" понимания проблемы - там ведь расписаны варианты для различных типов думаю что CTAC-KO это будет полезно.

Пример ,каюсь, писал прямо в форме ответа , не проверив - 5 просто опечатка , хотел 8 .

А почему я тоже вспомнил про "-" , толко позавчера делал формочку по остаткам - а они и + и -.
Тоже сразу не вспомнил что могут быть меньше нуля.
Слепил формочку для предпросмотра , для сортировки решил сделать индекс, а про "-" и забыл...
Вот и решил человека предостеречь от своей ошибки.
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186943
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ
Код: plaintext
INDEX ON DTOS(DATE) + STR( 10 ** 8 -Quantity, 8 ) TAG xXx

Все правильно, за исключением 10^8 надо 10^7. Поле Quantity имеет тип N(7) т.е. от -999999 до 9999999. соответственно (10^7 - Quantity) от 9000001 до 1. Все числа положительные, отсортируется нормально.
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186945
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да и STR(..., 7) можно сделать
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186949
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tда и STR(..., 7) можно сделать
про это я не подумав
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34186956
-=AlexiS=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати - CTAC-KO а индекс для чего ?
может лучше Select - у него в order by ASC / DESC можно указывать для каждой из колонок.
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34187092
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо за горячую дискуссию :)

Не знал про существование у Select-а order by ASC / DESC для каждой колонки, но это все равно не поможет в моем случае.

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

Попробую что даст функция с сайта Алексея Климова.

Т.е., как я понял, стандартных методов решения данной проблемы нет? Т.е. вшитых в фоксю?

ЗЫ Тут вот, к примеру, обсуждалась тема сортировки по клику в хедере, тока у вопрошавшей стоит вфп 5.0. Там поделилсь "велосипедом" в плане создания индекса тока по факту нажатия на хэдэр, а я вот еще при селекте сразу все индексы малюю и потом подумал - а нафига, можно ж наверное по запросу юзьверя. Вот и стал разбирать тот пример, немного его доработав
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34187120
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот он
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
IF NOT EMPTY(This.Parent.ControlSource)
   SELECT (This.Parent.Parent.RecordSource)
   * узнаем все индексы в массив
   ATAGINFO(arrTags)
   * имя тэга - по имени поля, начиная от позиции точка+ 1  до конца строки
   m.sFieldName = UPPER(ALLTRIM(SUBSTR(This.Parent.ControlSource,ATC(".",This.Parent.ControlSource)+ 1 )))
   * имя тэга не может быть больше  10  символов (или  11 ?)
   m.sTagName = LEFT(m.sFieldName, 10 )
   * запоминаем значение EXACT-а, для ASCAN важно чтобы SET EXACT ON был
   m.cSetExact = SET("EXACT")
   SET EXACT ON
  * Если тэг есть то SET ORDER, еси нет - INDEX 
   IF ASCAN(arrTags,m.sTagName) =  0 
      INDEX ON &sFieldName TAG &sTagName
   ELSE
      SET ORDER TO TAG &sTagName
   ENDIF
   *возвращаем SET EXACT
   SET EXACT &cSetExact
   this.Parent.Parent.Refresh
ENDIF

ну а затем думаю, мне зачастую приходится, например, индексировать по фамилии, а поскольку в моих данных важна еще дата, то я делал индекс типа name +DTOS(Date). Ну а как это реализовать в данном примере, если тут идея сама основана на 1 поле? Стал думать и теоретически дошел до идеи сортировки каждого поля в свою сторону, собственно в смартгриде так и есть.
...
Рейтинг: 0 / 0
Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
    #34187127
-=AlexiS=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор SmartGrid и есть Алексей Климов и функция используется именно для создания индексов "в лет".
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Возможно ли создание индекса из 2х полей чтобы каждое в разные стороны сортировались
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]