Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Ребят, нужна ваша помощь. Делаю это на VB6, но помощь нужна думаю ваша . Сделал ListView на API. Сделал сортировку по столбцу согласно MSDN. Сюда гляньте: Проблемы с ListView Т.е. есть указатель m_hMem1 с нуль-терминированной строкой в нем, указатель m_hMem2 с нуль-терминированной строкой в нем. Т.е. если я сравниваю строки как строки, то использую lstrcmp function : Код: vbnet 1. 2. 3. 4. 5. Это работает быстро и отлично. Могу использовать аналоги, например StrCmp function , либо что-то подобное, суть не меняется. А вот как быть с сортировкой по дата-время? Исходные данные: 1) m_hMem1 содержит указатель на нуль-терминированную строку с дата-время в тек. формате ОС 2) m_hMem2 содержит указатель на нуль-терминированную строку с дата-время в тек. формате ОС 3) Тек. формат ОС означает, что Россия: 12.06.2013 15:12:10 США: 06/12/2013 3:12:10 PM и т.д. Важно понимать что он всегда правильный на данном компьютере и воспринимается как IsDate=true. В VB6 у меня есть 2 железно работающих метода 1. Форматирование строки по такому формату даты (VB6 Format естественно понимает дата-время в тек. формате ОС ) Код: vbnet 1. 2. И далее сравниваем str1 и str2 как строки 2. Преобразование к As Date и тупо сравнение Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Почему я этим не хочу пользоваться. Преобразовать Код: vbnet 1. 2. или "сразу" получать String - не проблема. Но это очень медленная операция. Сравнение дат как As Date -тоже очень медленная операция. Т.е. по сути мне нужно быстро преобразовать Указатель h_Mem (дата-время в тек. формате Win) -> h_Mem (строка в формате "yyyymmddhhmmss") 1) Привязка к Win32 (иначе откуда код узнает тек. формат дата-время) 2) Отстутствие привязки к языку C++/VB (чтоб я мог это сделать из VB6) Win API понятно. Пытаюсь найти ответ здесь: Time (Windows) Но пока плаваю. Почему я написал в раздел C++, потому что у вас нет VB-шных Format, IsDate и надо же как то решать такие вопросы. Естественно чисто C-шные решения (абстрактно от Win-Linux) меня не устроят, потому как сделать это надо в VB и у меня завязка на системный "национальный" текущий формат дата-время. Как говорится Help please. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 14:13 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Ну, я пока нашел куда копать: VarDateFromStr Function Код: plaintext 1. 2. 3. 4. 5. 6. Но у меня в моем m_hMem указателе сидит LPTSTR а не OLECHAR . LVITEM structure Код: plaintext 1. 2. 3. 4. pszTextType: LPTSTR If the structure receives item attributes, pszText is a pointer to a buffer that receives the item text. Note that although the list-view control allows any length string to be stored as item text, only the first 260 TCHARs are displayed. Т.е. если я делаю вот так: Код: vbnet 1. 2. 3. 4. 5. 6. 7. То вот так не работает (при попытке скормить LPTSTR вместо OLECHAR которую она хочет): Код: vbnet 1. А вот так работает: Код: plaintext 1. 1) m_hMem1 (LPTSTR) -> VB6 as String 2) VB6 as String -> получаем новый указатель через StrPtr А задача как раз не связываться с VB-шными String, потому что они то и тормозят. Т.е. вопрос как подкинуть указатель на LPTSTR в ф-цию кот. хочет указатель на OLECHAR ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 16:29 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, Я не очень понимаю, зачем ты это сюда запостил, но ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 22:20 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
я не очень понимаю, почему ты с такими подходами пишешь на VB вместо C/C++. Проблема достаточно сложная и для С/С++. Сложная она прежде всего потому, что ты хранишь даты не в виде дат, а в виде строк в каком-то формате. А надо было бы наоборот -- хранить даты как даты, сравнивать их как даты, а показывать в виде строк. Это возможно сделать с SYSLISTVIEW со стилями OWNERDATA или ITEM с флагом CALLBACK (или как его там). Это так называемый virtual list view. В этих режимах ты хранишь данные у себя и не указываешь их в INSERT_ITEM, а потом, для отображения, SYSLISTVIEW посылает тебе сообщение для получения данных ITEM-а, кажется LVM_GETITEM. При этом сортировка тоже выглядит по-другому -- отсортировать тебе достаточно лишь твой буфер с данными, а потом лишь обновить видимую часть list view. Я бы копал в первую очередь в эту сторону. Но придётся практически всё переписать. Если оставаться в рамках существующего режима, то тебе нужно брать дату в виде строки, преобразовывать её в дату, и так же поступать с другим значением в сравнении, затем сравнивать значения как даты. Но это долго. Приемлимо только если мало записей в гриде. Ещё можно сделать такой гибридный вариант -- хранить ссылку на дату в виде даты в OWNERDATA (в каждой строке есть задаваемые пользователем данные размером с указатель), хранить можно в виде самих дат, если влезают, или в виде указателей на них. Тогда ты при сравнении можешь брать и сравнивать оригинальные даты, а не их образы в виде строк. Ещё можно было бы писать прогрессивный парсер-сравниватель-на-ходу для дат в виде строк в произвольном виндовом формате. На мой взгляд, это был бы ад кромешный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 22:37 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Спасибо за ответ. Запостил сюда потому что больше вероятность того что кто-то пишущий на C++ занимался родной сортировкой в API ListView. Виртуальный не хочу, итак все сейчас на API переписывал. Объектный в VB6 (с небольшими доработками через API) вполне хорош, но возникла злая проблема : Дмитрий77Есть Listview(Report), созданный в VB6 (Common Controls 5) Много записей. Одна выделена. Прокручиваем его так, чтоб выделенная запись была вне зоны видимости. Выполняем любую из команд: Код: vbnet 1. 2. 3. Проблема в том, что когда любая из них выполняется (не для выделенного, а для любого итема), то ListView делает для выделенной записи (для той кот. Selected) прокрутку в видимую область (EnsureVisible) Т.е. когда много записей, они постоянно добавляются и изменяются, невозможно даже сделать прокрутку (все время скручивает на выделенную запись). Поэтому имея достаточный опыт и сочтя проблему серьезной, решился таки нарисовать свой класс полностью опирающийся на API. Время убил, нарисовал, получилось. Изначальная то проблема этим решилась. Но сортировка через Custom-CallBack-и честно бесит своей скоростью. Прикол в том, что в объектном VB6 если есть 6500 строк, то родная сортировка строк - 30мс сортировка по датам с учетом хитрости "yyyymmddhhmmss" -200мс Я не знаю откуда у него такие хорошие показатели. Со строками я полечил, сравнивая по указателям . -результат 125мс (но все равно много если сравнивать с VB6 -30мс)- но куда копать уже не знаю. А вот с датами при использовании SysAllocString(m_hMem) минимум 700мс (против 200мс что имел в объектном) - причем неважно присваиваю ли я SysAllocString(m_hMem) напрямую переменной As Date (в VB так можно), либо пользую API VarDateFromStr Function . Я хотел скормить этой API указатель m_hMem (без преобразования в BSTR-соответствует VB-шной String через SysAllocString) но она его не ест. Почему? Просто непонятен прикол с такой "долгой сортировкой", вроде "по науке делаю". А этот глючный VB6 контрол это делает быстрее на порядок если не оптимизировать и в разы если пытаться оптимизировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 23:14 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
А чего я хочу, так это получить Date из указателя m_hMem на строку, минуя собственно преобразование в String (BSTR) -на что уходит основное к-во времени, причем с учетом "национальных настроек дата-время". Получение m_hMem через LVM_GETITEMTEXT (ну либо LVM_GETITEM) -в данном случае это одно и то же - операция быстрая. Сравнение Date - операция быстрая. А вот мазинации с промежуточными String (BSTR) -операции долгие. На 30мс конечно не рассчитываю, но на 200-250 вместо 700 вполне таки нормальное желание. А VB-шный объектный скорее всего как раз хранит данные в "параллельной структуре" и поэтому при сортировке не запрашивает LVM_GETITEMTEXT (LVM_GETITEM) -отсюда "скорость". В .Net например "своей" сортировки тоже нет, та же по сути кухня с CallBack-ами. Но писать свою объектную модель - это уже слишком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 23:29 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Вообще-то не совсем туда смотрел. VarDateFromStr function Код: plaintext 1. 2. 3. 4. 5. 6. LPCOLESTR -это указатель на Юникод-строку. Так? А я ее пытаюсь накормить указателем на ANSI-строку. Как мне из ANSI-указателя быстро получить Юникод указатель? Или? Я то использую LVM_GETITEMTEXT =LVM_GETITEMTEXTA (ANSI) М.б. рискнуть LVM_GETITEMTEXT =LVM_GETITEMTEXTW (Unicode)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2013, 23:51 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Или? Я то использую LVM_GETITEMTEXT =LVM_GETITEMTEXTA (ANSI) М.б. рискнуть LVM_GETITEMTEXT =LVM_GETITEMTEXTW (Unicode)? Получилось. Скормился. Скорости только не прибавилось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.11.2013, 00:06 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77LPCOLESTR -это указатель на Юникод-строку. Так? А я ее пытаюсь накормить указателем на ANSI-строку. Как мне из ANSI-указателя быстро получить Юникод указатель? По идее, bstrt -- это и есть "юникод указатель". Т.е. строка в UTF-16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.11.2013, 02:09 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
По идее, надо везде использовать W , LVM_GETITEMTEXT W , и так далее. Потому что для VB родная UTF-16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.11.2013, 02:11 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Если говорить о VB6, то там с Юникодом не очень хорошо. Поэтому у меня все коды A-ориентированы во избежании лишних проблем. Вот в .Net (изучаю потихоньку) я уже ориентируюсь на W. Но у нас речь не о VB6 а об API, иначе б я сюда не прилез с этим вопросом. И в данном конкретном случае API ф-ция VarDateFromStr требовала по определению Юникода, а я ее пытался кормить A-указателем, вот она и не видела дату-время в строке. Но как выяснилось эта VarDateFromStr мало что дает по скорости. С таким же успехом я мог вернуть SysAllocString(m_hMem) as String, либо сразу объявить в LVITEM параметр как String и присвоить этот String переменной Date. Должен быть какой-то более быстрый способ конвертации в дату-время. Или его просто нет, а объектный ListView выруливает чисто за счет хранения текстов вне итемов, как я предположил выше. Собственно то о чем ты и писал. Но так ли это или можно что-то сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.11.2013, 03:15 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77MasterZiv, Если говорить о VB6, то там с Юникодом не очень хорошо. Поэтому у меня все коды A-ориентированы во избежании лишних проблем. Вот в .Net (изучаю потихоньку) я уже ориентируюсь на W. Это как-то очень странно. Я никогда эту хрень не использовал (а нет, однажды всё же юзал), но я знаю, что весь OLE на UTF16. А весь VB на OLE AUTOMATION. Дмитрий77Должен быть какой-то более быстрый способ конвертации в дату-время. Или его просто нет, а объектный ListView выруливает чисто за счет хранения текстов вне итемов, как я предположил выше. Собственно то о чем ты и писал. Но так ли это или можно что-то сделать? Не думаю, что есть "какой-то более быстрый способ конвертации в дату-время". Даже если есть такой способ, то уже одна идея что-то преобразовывать внутри сортировки порочна. Алгоритмы сортировки -- это либо Nlog N , либо N*N. Это тебе столько преобразований надо сделать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.11.2013, 18:49 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Спасибо за участие. Мне удалось наконец обогнать объектный Listview в плане сортировки по дата/время. Фокус с "yyyymmddhhmmss" (во временный столбец) дает прирост скорости в 4 раза. Конвертация в даты и их сравнение - накладная операция. А сравнивая даты я вызываю эту конветацию минимум в 2 раза большее к-во раз. С твоего позволения привожу здесь конечный код целиком, м.б. кому пригодится. Переводить VB->C++ проще чем сочинять. Дмитрий77Antonariyпропущено... Тут и Left, и Format... Вряд ли. Еще как ускорится. Мне удалось наконец обогнать объектный ListView в сортировке дат, использую по сути тот же способ "yyyymmddhhmmss" Результаты для 6500 строк: Объектный Дата/время - 220-250мс; Строки - 30мс API-шный Дата/время - 170-190мс; Строки - 70-90мс (было изначально без оптимизации: Дата/время - 1000-2000мс; Строки - 350-400мс ) Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. В принципе на этом можно сказать СТОП. Честно, пытался еще перекидывать данные в нулевой столбец и выполнять "родную" сортировку Код: vbnet 1. 2. 3. 4. 5. 6. Но она сволочь в run тайме не работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.11.2013, 20:29 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77, Я не понял особенно, чем же я тебе помог, но я рад. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.11.2013, 01:34 |
|
||
|
Сортировка Listview по date-time. Сравнить 2 строчки с дата/время. Есть указатели на них.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77MasterZiv, Спасибо за участие. Мне удалось наконец обогнать объектный Listview в плане сортировки по дата/время. Фокус с "yyyymmddhhmmss" (во временный столбец) дает прирост скорости в 4 раза. Конвертация в даты и их сравнение - накладная операция. А сравнивая даты я вызываю эту конветацию минимум в 2 раза большее к-во раз. Создай постоянный столбец с "yyyymmddhhmmss" и спрячь его, выставив ширину в 0. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2013, 08:13 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38449168&tid=2019889]: |
0ms |
get settings: |
7ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
163ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 258ms |

| 0 / 0 |
