Форум » [x]Harbour » Новые типы переменных ? » Ответить

Новые типы переменных ?

Andrey: Подскажите пожалуйста, а с какого времени существуют новые типы данных в базах Харбор/хХарбор ? + AutoInc 4 Auto increment = ModTime 8 Last modified date & time of this record ^ RowVers 8 Row version number; modification count of this record @ DayTime 8 Date & Time I Integer 1, 2, 3, 4 or 8 Signed Integer ( Width : )" },; T Time 4 or 8 Only time (if width is 4 ) or Date & Time (if width is 8 ) (?) V Variant 3, 4, 6 or more Variable type Field Y Currency 8 64 bit integer with implied 4 decimal B Double 8 Floating point / 64 bit binary Не заметил разницы между этими типами (или не понял): + AutoInc 4 Auto increment ^ RowVers 8 Row version number; modification count of this record Кто может разъяснить их применение ? Какой максимальный размер импорта файла для типов: M Memo P Picture B Blob V VarField Не смог записать ни в одно поле файл размером 3198 Мб через утилиту DBedit. Ошибка - [more] Application Internal Error - c:\clipbin\dbedit.exe Terminated at: 2013.05.06 13:00:49 Неисправимая ошибка 9006: hb_xgrab не может распределить память Called from MEMOREAD(0) Called from _FREAD(0) in \ts\clip50.lib\_EDITMEM.prg Called from USER(0) in \ts\clip50.lib\_EDITMEM.prg Called from (b)EDITMEMO(0) in \ts\clip50.lib\_EDITMEM.prg Called from TEXTEDIT(0) in \ts\clip50.lib\_TEXT.prg Called from EDITMEMO(0) in \ts\clip50.lib\_EDITMEM.prg Called from EDITVARFIELD(1600) in source\dbedit.prg Called from (b)GETCOL(1573) in source\dbedit.prg Called from GETBROWSE(0) in \ts\clip50.lib\_editbro.prg Called from EDITBROWSE(0) in \ts\clip50.lib\_editbro.prg Called from DBMENU(0) in \ts\clip50.lib\_dbmenu.prg Called from MAIN(821) in source\dbedit.prg [/more] Может что не так делаю ?

Ответов - 158, стр: 1 2 3 4 5 6 7 8 All

Dima: Andrey пишет: Подскажите пожалуйста, а с какого времени существуют новые типы данных в базах Харбор/хХарбор ? c 2009 вроде

Pasha: Andrey пишет: Неисправимая ошибка 9006: hb_xgrab не может распределить память Это ошибка выделения памяти. Здесь действуют несколько ограничений: 1. Максимальный размер символьной переменной 2. Максимальный размер мемо-поля Какие там ограничения - 2Г или больше - сразу не скажу 3. Ограничение на выделение памяти (размер физической или виртуальной памяти). В мемо-поле данные записываются целиком, поэтому и считать файл в память надо целиком. Но это плохое решение - загонять гигабайты в мемо-поле. Оно все-таки для этого не предназначено.

Andrey: Pasha пишет: Но это плохое решение - загонять гигабайты в мемо-поле. Оно все-таки для этого не предназначено. Согласен. Просто протестировал по максиму. Думаю 1-5 Мб размер файла картинки будет нормально для базы ? И какое поле базы лучше использовать для картинок (jpg, bmp...) ? M Memo P Picture B Blob V VarField И для чего нужно поле типа "V" (если уже есть M, P, B) ?


Pasha: Andrey пишет: Думаю 1-5 Мб размер файла картинки будет нормально для базы ? Нормально И какое поле базы лучше использовать для картинок (jpg, bmp...) ? M Memo P Picture B Blob V VarField Если нет перекодировки кодовых страниц, то все равно: M, P или B Если есть - то M использовать нельзя. И для чего нужно поле типа "V" (если уже есть M, P, B) ? V - это другой тип поля, более сложный. О нем лучше почитать в ng по six3. Там даже есть отдельный раздел: VarField "V" Field Types

Andrey: Подскажите пожалуйста, как можно переделать свой dbf под новое поле: + AutoInc (Auto increment). Дело в том что у меня есть в базе поле ID записи, которое я веду сам. Хочу сделать новое ID2, но с сохранением значений ID (база чистилась и ID идут не по порядку RECNO() ). Как это сделать ?

Andrey: Поставил в базу поле ID тип + AutoInc 4 Auto increment. Теперь при добавлении записи получаю ошибку: Error DBFCDX/1020 Ошибка типа данных: ID Код такой: aFieldArray := { } GetFields( aFieldArray ) APPEND BLANK ALERT( STR(FIELD->ID)+";"+VALTYPE(FIELD->ID) ) FOR nI := 1 TO FCOUNT() FIELDPUT( nI, aFieldArray[ nI ] ) NEXT Причем VALTYPE(FIELD->ID) возвращает N - Как получить правильный тип поля базы ? Как сделать правильно ?

Pasha: Поле AutoInc не предназначено для изменения. Оно заполняется автоматически при добавлении записи. При попытке что-либо записать в поле возникает ошибка EDBF_DATATYPE

Andrey: Pasha пишет: Поле AutoInc не предназначено для изменения. А как тогда получить, что это тип поля AutoInc ? VALTYPE(FIELD->ID) возвращает N !

Dima: Andrey пишет: А как тогда получить, что это тип поля AutoInc ? Пробни HB_FIELDTYPE()

Vlad04: А как объявить поле Auto increment ? Только программно ? Во вьюверах ничего такого нет.

Dima: Vlad04 пишет: А как объявить поле Auto increment ? вероятно тип поля "+" типа так dbcreate("test",{{"tst","n",1,0},{"incrtest","+",3,0}},,.t.)

Andrey: Vlad04 пишет: Только программно ? Во вьюверах ничего такого нет. Пашина утилита dbedit.exe - позволяет делать это. Да и многое другое !!!

Andrey: Dima пишет: Пробни HB_FIELDTYPE() Возвращает пустую строчку. У меня хХарбор 1.2.3

Dima: Andrey пишет: Возвращает пустую строчку Нет у меня хХарбор ;) Попробуй для теста Harbour , он же есть у тебя. Хотя кто знает может в хХарбор нужно юзать FIELDTYPE() , не проверял.

Dima: Andrey пишет: Возвращает пустую строчку. Hb_fieldtype(номер поля) // норм работает

Andrey: Dima пишет: Hb_fieldtype(номер поля) // норм работает Да - работает ! Описание в Хелпе по хХарбору нет, а я поставил имя поля.... Из-за этого и не сработало раньше. Спасибо БОЛЬШОЕ Дима !

Softlog86: Andrey вроде Вы используете DBF для хранения картинок ? У меня задача такая-же . Нужно помимо прочих стоково/числовых значений ещё и фото товара . Посоветуйте как лучше сделать ? На сегодняшний день я картинки держу в MEMO ... и перед просмотром записываю в файл и соответсвенно показ . Чую что есть лучшее решение .... HARBOUR + MiniGui

Dima: Softlog86 Зачем так усложнять ? Храните картинки как они есть в отдельной папке.

Sergy: Dima пишет: Softlog86 Зачем так усложнять ? Храните картинки как они есть в отдельной папке. +1 Если артикулов много - значит много будет картинок. Зачем нагружать систему, сваливая все в одну кучу, если можно удобно и комфортно хранить jpg файлы в отдельном каталоге ? Добавлю, что картинки (в отличие от самой БД) в большинстве случаев меняются гораздо реже, поэтому - какой смысл регулярно бекапить статичную по сути информацию ?

Andrey: Softlog86 пишет: На сегодняшний день я картинки держу в MEMO ... и перед просмотром записываю в файл и соответсвенно показ . Чую что есть лучшее решение .... HARBOUR + MiniGui 1) Надо не забыть, что и в HARBOUR'e можно показывать картинки в терминале GTWVT. Смотрите примеры терминала GTWVT (он сейчас по другому называется GTWVG) или мой пример с фонтами (я его здесь на форуме выкладывал). 2) Можно сделать внешний показ картинки на МиниГуи - см. пример библиотеки - сохранения и показ графических файлов в базе формата DBFCDX в папке samples\Basic\Image2Dbf 3) Можно базу и показ товара сразу сделать на МиниГуи. Типа такого: Но это сложно. Я пока сам разбираюсь. Все зависит от конкретной задачи. Какие картинки нужно показывать, как часто их показывать и т.д. Выбор ваш. Если большие картинк, то может и не нужно их в базе хранить. Не знаю. Я раньше doc файлы хранил в базе, потом отказался, потому что база пухнет и копии файлов хранить неудобно.

Softlog86: У меня вся программа на HARBOUR в GUI (MiniGUI) . Почему храню в одном файле ? 1) Файлов очень много ( больше 4-х тысяч) - нагрузка на файловую систему большая и это чувствуется ...... 2) С точки зрения интеллектуальной собственности ( трудов на создание графики было потрачено ого-го) - так что украсть картинки становится сложнее 3) Компактность всей системы : мне проще хранить несколько тысяч картинок в 1-м ( по правде в 2-х файлах :DBF + FPT ) = 170 МБ в общем - тема хранения в отдельном каталоге пофайлово не рассматривается . До этого вся графика зиповалась с паролем и доставалась для показа - но были потери во времени и иногда программа самопроизвольно вываливалась ( не смог победить) ...

Andrey: Softlog86 пишет: До этого вся графика зиповалась с паролем и доставалась для показа JPG-файл зиповать бесполезно... Лучше его криптовать - HB_Crypt(). Softlog86 пишет: иногда программа самопроизвольно вываливалась ( не смог победить) Записывай графику в базу с помощью функций из примера samples\Basic\Image2Dbf

ММК: Softlog86 пишет: 2) С точки зрения интеллектуальной собственности ( трудов на создание графики было потрачено ого-го) А можно увидеть хотя бы одну единственную? Andrey пишет: JPG-файл зиповать бесполезно... Почему?

Softlog86: Зиповал не для уменьшения объема ( JPG сам по себе сжат) .... а ради сохранения всех файлов в одном хранилище с невозможностью достать из него ( конечнно умельцы смогут ... но какими средствами) Как я уже написал выше , цель спрятать картинки - чтоб конкурентам не упрощать работу .... пусть сами делают фото всех своих товаров ..... Пока ( уже три года) записываю в MEMO и меня в общем-то устраивает .... :) Не зная алгоритма выдернуть картинку из этого мемо не получится ..... так как ещё пишутся кой-какие ключи ... да и байты не в прямом порядке как они идут в настоящем JPG ...... в общем своего рода двойное криптование . Не в этом суть . Я спрашивал про запись JPG в поля новых типов .... Всем откликнувшимся - С П А С И Б О !!!!

Andrey: HB_Crypt() лучшая функция для защиты, чем pkzip с ключом. Если писать в мемо поле fpt, то при некоторых значениях в строке, будет вылет базы, т.е. строку нужно преобразовать, заменить chr(26) и chr(0). Лучше картинки держать в P Picture или B Blob. Но как работать с этим я не знаю. Пробовал сделать пример не получилось. База не создается. Может кто даст примеры по работе с такими переменными ?

SergKis: Softlog86 пишет: иногда программа самопроизвольно вываливалась ( не смог победить) Попробуйте расставить в программе принудительную сборку мусора. У прогр. на MiniGui, при разрастании режимов, появляются такие особенности - у нас это было так. Вставка hb_gcAll(.T.) перед созданием окон - помогла.

Softlog86: На базе image2dbf и делалось .... :) . А тут прочитал что есть новые типы полей и задумался ......

Andrey: Всем привет. Вот опять вопрос про поле AutoInc (Auto increment): Как этот тип поля надежен в плане уникального ID ? Если в базе удалять записи, а потом сделать pack базы, ID по всей базе не изменится ? Кто пользуется этим типом поля ? Поделитесь опытом.

Pasha: Тест показал, что после pack значения autoinc полей не изменяются.

gfilatov2002: Pasha пишет: Тест показал, что после pack значения autoinc полей не изменяются. Подтверждаю. Мой тестовый пример см. ниже [pre2]/* * MINIGUI - Harbour Win32 GUI library Demo */ #include "minigui.ch" #include "Dbstruct.ch" REQUEST DBFCDX Function Main SET CENTURY ON SET DELETED ON SET BROWSESYNC ON DEFINE WINDOW Form_1 ; AT 0,0 ; WIDTH 640 HEIGHT 480 ; TITLE 'MiniGUI Browse Demo' ; MAIN NOMAXIMIZE ; ON INIT OpenTables() ; ON RELEASE CloseTables() DEFINE MAIN MENU POPUP 'File' ITEM 'Set Browse Value' ACTION Form_1.Browse_1.Value := Val ( InputBox ('Set Browse Value','') ) ITEM 'Get Browse Value' ACTION MsgInfo ( Str ( Form_1.Browse_1.Value ) ) ITEM 'Refresh Browse' ACTION Form_1.Browse_1.Refresh SEPARATOR ITEM 'Get Struct' ACTION ( astr := dbstruct(), MsgInfo ( astr[1][2], astr[1][1] ) ) SEPARATOR ITEM 'Exit' ACTION Form_1.Release END POPUP POPUP 'Help' ITEM 'About' ACTION MsgInfo ("MiniGUI Browse Demo") END POPUP END MENU DEFINE STATUSBAR STATUSITEM '' END STATUSBAR @ 10,10 BROWSE Browse_1 ; WIDTH 610 ; HEIGHT 390 ; HEADERS { 'Code' , 'First Name' , 'Last Name', 'Birth Date', 'Married' , 'Biography' } ; WIDTHS { 100 , 150 , 150 , 150 , 150 , 150 } ; WORKAREA Test ; FIELDS { 'Test->Code' , 'Test->First' , 'Test->Last' , 'Test->Birth' , 'Test->Married' , 'Test->Bio' } ; TOOLTIP 'Browse Test' ; ON CHANGE ChangeTest() ; JUSTIFY { BROWSE_JTFY_RIGHT,BROWSE_JTFY_CENTER, BROWSE_JTFY_CENTER, BROWSE_JTFY_CENTER,BROWSE_JTFY_CENTER,BROWSE_JTFY_CENTER} END WINDOW CENTER WINDOW Form_1 Form_1.Browse_1.SetFocus ACTIVATE WINDOW Form_1 Return Nil Procedure OpenTables() if !file("test.dbf") CreateTable() endif Use Test Via "DBFCDX" Shared Go Top Form_1.Browse_1.Value := RecNo() Return Procedure CloseTables() Use Return Procedure ChangeTest() Form_1.StatusBar.Item(1) := 'RecNo() ' + Alltrim ( Str ( RecNo ( ) ) ) Return Procedure CreateTable LOCAL aDbf[6][4], i aDbf[1][ DBS_NAME ] := "Code" aDbf[1][ DBS_TYPE ] := "+" aDbf[1][ DBS_LEN ] := 4 aDbf[1][ DBS_DEC ] := 0 // aDbf[2][ DBS_NAME ] := "First" aDbf[2][ DBS_TYPE ] := "Character" aDbf[2][ DBS_LEN ] := 25 aDbf[2][ DBS_DEC ] := 0 // aDbf[3][ DBS_NAME ] := "Last" aDbf[3][ DBS_TYPE ] := "Character" aDbf[3][ DBS_LEN ] := 25 aDbf[3][ DBS_DEC ] := 0 // aDbf[4][ DBS_NAME ] := "Married" aDbf[4][ DBS_TYPE ] := "Logical" aDbf[4][ DBS_LEN ] := 1 aDbf[4][ DBS_DEC ] := 0 // aDbf[5][ DBS_NAME ] := "Birth" aDbf[5][ DBS_TYPE ] := "Date" aDbf[5][ DBS_LEN ] := 8 aDbf[5][ DBS_DEC ] := 0 // aDbf[6][ DBS_NAME ] := "Bio" aDbf[6][ DBS_TYPE ] := "Memo" aDbf[6][ DBS_LEN ] := 10 aDbf[6][ DBS_DEC ] := 0 // DBCREATE("Test", aDbf, "DBFCDX") Use test Via "DBFCDX" For i:= 1 To 100 append blank Replace First With 'First Name '+ Str(i) Replace Last With 'Last Name '+ Str(i) Replace Married With .t. replace birth with date()+i-10000 Next i delete all for recno()%10==0 PACK Use Return [/pre2]

Andrey: Ну спасибо БОЛЬШОЕ ! Значит можно применять у себя в задачах ! Вот только для новых типов полей нет программ просмотра, кроме программы dbedit !

Vlad04: Вот только для новых типов полей нет программ просмотра А.Кресина консольные просмотрщики нормально открывают. Фильтровать можно по ключевому полю, редактировать все остальные поля,кроме autoinc ,но так оно и должно быть.

Andrey: Искал по форуму, не нашёл. Хотя помню, что уже спрашивал... Как определить, есть ли такая переменная в программе. Т.е. определена ли GLOBAL переменная или нет ?

Dima: Andrey пишет: Как определить, есть ли такая переменная в программе. http://clipper.borda.ru/?1-4-0-00000671-000-0-0-1313577707 PS Писать надо было не в этой теме а во ФЛЕЙМЕ

Andrey: Спасибо !

Dima: Andrey пишет: переменная в программе вбиваем это в поиск , жмем плюсик с права и ставим галю искать все слова .....всего одна страничка результат

Andrey: Пытаюсь работать с новым типом поля "+" AutoInc 4 Auto increment Есть база с полем ID тип "+". Допустим numba - учетный уникальный номер в этой базе (сплошной). Нужно ли делать индексный файл по этому полю для поиска типа SEEK(numba) или можно обойтись DBGOTO(numba) ??? А если база была упакована, то можно проверить IF FIELD->ID # numba .... Что будет быстрей ? Проще наверно без доп. индекса. Но может я и неправ. Подскажите пожалуйста.

SergKis: Andrey пишет:Проще наверно без доп. индекса. Но может я и неправ Не надо путать (совмещать) + и RecNo. Пример (в dbf 1000 записей) copy to 10 записей, delete их же и pack, append from тех же десяти записей и получим LastRec такой же, а RecNo не совпадает с ID +. Выводы делай сам

Sergy: Andrey пишет: А если база была упакована, то можно проверить IF FIELD->ID # numba .... Что будет быстрей ? Проще наверно без доп. индекса. Но может я и неправ. Подскажите пожалуйста. GOTO будет ВСЕГДА быстрей. Потому что сначала идет вычисление по индексу, после чего - GOTO на нужную запись. Если таблица наподобие справочника, из которого никогда не будут удаляться записи (id) - тогда можно не использовать "+" autoinc поле, достаточно будет RECNO() в качестве идентификатора. Во всех остальных случаях (COPY TO, APPEND FROM..., PACK..., SORT...) - без уникального ID не обойтись. И autoinc-поле вполне надежный помощник в данном случае.

SergKis: Sergy пишет:Если таблица наподобие справочника, то вполне можно и locate обойтись и наличие индекса на + не большая нагрузка. Если вы один разработчик базы, то можно рассчитывать на работу без pack и применения утилит типа dbedit (продвинутым пользователем), иначе возможны риски ..., а так да "autoinc-поле вполне надежный помощник"

Andrey: Вывожу поле "=" или "@" через cValToChar((Alias())->TS) Получаю только "19.08.15" Как правильно выводить ?

SergKis: Andrey Пробуй: HB_TSTOSTR HB_TTOC HB_TTOD HB_TTON HB_TTOS HB_STOT HB_STRTOTS

Dima: Andrey HB_TSTOSTR (HB_DATETIME()) остальное не пробовал , так что пробуй , Сергей верно написал.

Andrey: Dima пишет: HB_TSTOSTR (HB_DATETIME()) То что надо !

Dima: Получил в логе (у клиента) ошибку 9006 hb_xgrab при создании индекса локально. У себя повторить тот же момент не смог. Правда у меня там косяк был типа index on str(cod,6)+skl_in TAG (zk) где zk:=TMMP+alltrim(left(sys_name,5))+"zwk" а переменная TMMP равна getenv("TEMP")+"\" но у меня не падает зараза Имя тега обрежется (проверил) если задано шибко длинное. Переделал на index on str(cod,6)+skl_in TAG tmp2 , буду наблюдать. PS DBFCDX

MIKHAIL: Попробовал добавить в БД тип поля AI + при открытии в ADS выдает ошибка, такой тип ADS не поддерживает?

Dima: MIKHAIL Глянь HELP http://devzone.advantagedatabase.com/dz/webhelp/advantage9.0/server1/dbf_field_types_and_specifications.htm Насколько я понял из сырца тип надо указать как "+"

MIKHAIL: Dima пишет: Насколько я понял из сырца тип надо указать как "+" Да, создает, но тип фалов ADSVFP, тип поля при этом определяет как числовой. У меня есть некоторые сомнения, если потом буду на Letodb переводить, будет ли он понимать эти таблицы или лучше не париться а использовать числовое поле и уникальный индекс в DBFCDX ?

Dima: MIKHAIL пишет: будет ли он понимать эти таблицы я бы проверил , но чую что должен понимать.

Haz: В ADS есть все типы полей. Догадываюсь что AI это автоинкремент В ADS поле называется AUTOINC. Все поддердиваемые типы есть в справе

Andrey: Использую в DBFCDX поле "+" AutoInc. Раньше (ещё в клипере) вёл свой AutoInc через отдельную базу. Хочу переделать. Можно ли как то изменить этот номер ? Нужно проставить свои значения в поле AutoInc.

SergKis: Andrey пишет:Можно ли как то изменить этот номер ? Поле защищено от записи. Свои значения можно получить в поле создав базу в последовательности старых значений и заполнив "дырки"

Andrey: SergKis пишет: Поле защищено от записи. В других базах это поле править можно ! Очень жалко... SergKis пишет: Свои значения можно получить в поле создав базу в последовательности старых значений и заполнив "дырки" Да дебилизм получается... У меня ID свой у некоторых заказчиках очень большой есть, типа 2315032. В своё время делал разноску по филиалам и надавал большие ID филиалам. Дырки заполнять не надо, пускай остаются. Со справочниками улиц тоже фигня получается. Лет 15 назад сделал его, переделать на новое поле получается нельзя.

SergKis: Andrey пишет: У меня ID свой у некоторых заказчиках очень большой Думаю путаешь Autoincrement (+1 с фиксацией в заголовке dbf) и логический ID записи, формируемый какими то алгоритмами.

Andrey: SergKis пишет: логический ID записи, формируемый какими то алгоритмами. Да вот захотел этот свой логический ID переделать на правильный AutoInc.

Sergy: Думаю, реально запросить у разработчиков место хранения инкрементного поля Harbour тут: https://groups.google.com/forum/#!forum/harbour-users После чего двоичным редактором поправить на нужное значение. Либо функция RDDI_*, DBI_* какая-то отвечает за это... Так же стоит обратить внимание на алгоритм работы autoinc полей в случае команды APPEND FROM: в принимающей базе эти поля продолжат наращивать свое значение последовательно, вне зависимости от значения полей источника. Это позволяет исключить ситуацию появления двух одинаковых значений.

Петр: Andrey пишет: Использую в DBFCDX поле "+" AutoInc. Раньше (ещё в клипере) вёл свой AutoInc через отдельную базу. Хочу переделать. Можно ли как то изменить этот номер ? Нужно проставить свои значения в поле AutoInc. Для новых наработок используйте "I:+", 8, например dbCreate( "tablewithai", { { "AI", "I:+", 8, 0 } } ) Тогда и поле менять сможете, и "большой ID" использовать Кстати, через ..опу, можете попробовать старые справочники импортировать.

Andrey: Петр пишет: Для новых наработок используйте "I:+", 8, Что за новый тип поля ?

Dima: Andrey пишет: Что за новый тип поля ? Петр все же описал :) До кучи [pre2] 2015-02-17 16:35 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rdd/dbf1.c + added support for autoincrement fields with counter longer then 4 bytes Warning: if someone created tables with such fields i.e. { "I:+", 8, 0 } after my modification which added support for AutoInc flags in all numeric DBF fields then he should update counters manually using DBS_COUNTER flag. New code uses 64bit counters for such field located in different part of DBFFIELD structure. [/pre2]

Andrey: А есть примеры как это делать ? DBS_COUNTER flag - как его использовать ?

Dima: Andrey пишет: DBS_COUNTER flag - как его использовать ? Инфа на подумать... [pre2] 2012-06-18 17:33 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * harbour/include/dbinfo.ch * harbour/src/rdd/dbf1.c + added new dbFieldInfo() actions: DBS_COUNTER - get/set autoincrement field counter DBS_STEP - get/set autoincrement field step * reset autoincrement and row version fields in ZAP operation [/pre2]

Dima: Видать так dbFieldInfo( DBS_COUNTER, FieldPos( <cFieldName> ) )

Петр: Dima пишет: Видать так dbFieldInfo( DBS_COUNTER, FieldPos( <cFieldName> ) ) В этом случае мы получим текущее значение счетчика для поля <cFieldName> А так мы можем его изменить oldCounterValue := dbFieldInfo( DBS_COUNTER, FieldPos( <cFieldName> ), newCounterValue ) dbCreate( "tableWithAI", { { "AI", "I:+", 8, 0 } } ) USE tableWithAI NEW dbFieldInfo( DBS_COUNTER, FieldPos( "AI" ), 10 ) dbFieldInfo( DBS_STEP, FieldPos( "AI" ), 2 ) FOR i := 1 TO 3 APPEND BLANK NEXT i FOR i := 1 TO 3 dbGoto(i) ? FIELD->AI NEXT i dbGoto(2) FIELD->AI := 11 FOR i := 1 TO 3 dbGoto(i) ? FIELD->AI NEXT i USE И еще по типам данных полей БД 2015-02-08 13:19 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rdd/workarea.c + added support for field flags in dbCreate()/dbStruct(). Flags can be passed in string with field type after ":", i.e. "C:U" means Unicode character field. The following flags are recognized: "N" - column can store null values "B" - binary column "+" - column is autoincrementing "Z" - column is compressed "E" - column is encrypted "U" - column stores Unicode strings

Andrey: Петр пишет: И еще по типам данных полей БД "Z" - column is compressed "E" - column is encrypted Это что за интересный тип полей ? Т.е. можно туда допустим текстовый файл передать, он будет храниться в архивном виде ? Какая длина поля максимальная по этому типу ? А другой тип для чего ? Всё интересней и интересней...

Петр: Andrey пишет: Это что за интересный тип полей ? Это не тип полей, это свойства полей, т.н. "field flags" - i.e. "C:Z" или "M:Z" или "B:Z" Т.е. поле символьное сжатое или мемо сжатое или.. Andrey пишет: Какая длина поля максимальная по этому типу ? см. выше Andrey пишет: А другой тип для чего ? опять-таки не тип, а поле символьное зашифрованое или мемо зашифрованое или.. Andrey пишет: Т.е. можно туда допустим текстовый файл передать, он будет храниться в архивном виде ? Храниться будет в том виде, в котором поместите. До сих пор за все манипуляции с полями dbf файла отвечает программист. Автоматически ничего не будет ни сжиматься, на шифроваться. По крайней мере сейчас, дальше все могет быть. Так что или ждите или пишите usrrdd, используйте hb_gzipio - "полуфабрикатов" в harbour предостаточно.

Andrey: Петр пишет: dbCreate( "tableWithAI", { { "AI", "I:+", 8, 0 } } ) Добавил такое поле в базу. При создании базы счётчик есть. После этого при добавлении записей - поле по нулям. Т.е. нет приращения в поле. Пробовал в утилите Павла - dbedit.exe

Dima: Andrey пишет: Пробовал в утилите Павла - dbedit.exe Пробовать надо не в утилите Она не понимает формат поля "I:+" Проверил работает , смотри пример выше , Петр давал. Но Harbour должен быть не старее чем февраль 2015 , иначе ни куя не сработает. Кроме того не известно каким Harbour собран Dbedit

Andrey: Dima пишет: Но Harbour должен быть не старее чем февраль 2015 Собирал на новом МиниГуи, там Харбор свежее. А хХарбор поддерживает эти типы полей ?

Dima: Andrey пишет: Собирал на новом МиниГуи, там Харбор свежее. Значит там работает

Andrey: Dima пишет: А глянь пример C:\MiniGUI\SAMPLES\Advanced\RibbonBar\ Спасибо Дима ! То что нужно. Там вверху стоит FIELD NOMBRE,DIRECCION,LOCALIDAD,PAIS,CODPOST,;

Dima: Andrey А темку я перенес по ходу http://clipper.borda.ru/?1-4-0-00001153-000-0-0-1473335505

Andrey: Всем привет. Сделал года два назад своё поле IMZ типа: @ DayTime 8 Date & Time Сергей ранее писал про него, что туда нужно самому писать. Ничего в него не писал никогда, сейчас собрался его подключить и вижу, что некоторые записи уже исправлены: Как такое могло случиться ? Блин, как в кино: не виновата я, он сам пришёл....

Dima: Andrey пишет: Как такое могло случиться ? Сам и записал , но забыл как обычно

Andrey: Dima пишет: Сам и записал , но забыл как обычно Да обыскал все свои исходники - нет у меня записи нигде в поле IMZ. Может ли такое случить (самопроизвольно) если базы копировались из одной в другою ?

Pasha: В поле @ aka TimeStamp dbfcdx автоматически записывает время последнего изменения текущей записи.

Andrey: Уф... Теперь стало понятней. А какое поле можно сделать для своего редактирования для типа поля TimeStamp ?

SergKis: ChangLog.txt. 2009-11-25 19:10 ; Current field type mappings are: C; Character,n HB_FT_STRING,n ADS_STRING N; Numeric,n,d HB_FT_LONG,n,d ADS_NUMERIC D; Date,n HB_FT_DATE,3 or 4 or 8 ADS_COMPACTDATE; ADS_DATE ShortDate HB_FT_DATE,3 ADS_COMPACTDATE L; Logical HB_FT_LOGICAL,1 ADS_LOGICAL M; Memo,n HB_FT_MEMO,4 or 9 or 8 ADS_MEMO B; Double,,d HB_FT_DOUBLE,8,d ADS_DOUBLE I; Integer,n HB_FT_INTEGER, 2 or 4 or 8 ADS_SHORTINT; ADS_INTEGER; ADS_LONGLONG ShortInt HB_FT_INTEGER,2 ADS_SHORTINT Longlong HB_FT_INTEGER,8 ADS_LONGLONG P; Image HB_FT_IMAGE,9 or 10 ADS_IMAGE W; Binary HB_FT_BLOB,4 or 9 or 10 ADS_BINARY Y; Money HB_FT_CURRENCY,8,4 ADS_MONEY Z; CurDouble,,d HB_FT_CURDOUBLE,8,d ADS_CURDOUBLE T,4; Time HB_FT_TIME,4 ADS_TIME @; T,8; TimeStamp HB_FT_TIMESTAMP,8 ADS_TIMESTAMP +; AutoInc HB_FT_AUTOINC,4 ADS_AUTOINC ^; RowVersion HB_FT_ROWVER,8 ADS_ROWVERSION =; ModTime HB_FT_MODTIME,8 ADS_MODTIME Raw,n HB_FT_STRING,n (+HB_FF_BINARY) ADS_RAW Q; VarChar,n HB_FT_VARLENGTH,n ADS_VARCHAR; ADS_VARCHAR_FOX VarBinary,n HB_FT_VARLENGTH,n (+HB_FF_BINARY) ADS_VARBINARY_FOX; ADS_RAW CICharacter,n HB_FT_STRING,n ADS_CISTRING

Sergy: Pasha пишет: В поле @ aka TimeStamp dbfcdx автоматически записывает время последнего изменения текущей записи. Уверен, что Harbour сам никогда ничего не пишет в поле типа "@" (FT_TIMESTAMP). Потому что для этого предназначено поле типа "=" (FT_MODTIME). Andrey пишет: А какое поле можно сделать для своего редактирования для типа поля TimeStamp ? Уточню - что указанное поведение полей "@" и "=" относится к Harbour. Как с этим в xH - не в курсе.

SergKis: Sergy для xhb ставим RddInfo( RDDI_TABLETYPE, DB_DBF_VFP ) и тоже ок. letodb 1-ой версии (2х поточная) сервер собирался на xhb, это использует, на клиент не передаются такие поя, но с триггером на сервере ок.

Pasha: Sergy пишет: Уверен, что Harbour сам никогда ничего не пишет в поле типа "@" (FT_TIMESTAMP). Потому что для этого предназначено поле типа "=" (FT_MODTIME). В Harbour это так. А в xHarbour в функции hb_dbfUpdateStampFields время пишется и в HB_FT_TIMESTAMP, и в HB_FT_MODTIME

Andrey: Pasha пишет: В Harbour это так. А в xHarbour в функции hb_dbfUpdateStampFields время пишется и в HB_FT_TIMESTAMP, и в HB_FT_MODTIME Понял я в чем дело. У меня базы работают одновременно и с терминалкой (хХарбор) и на МиниГуи (Харбор). Значит это мне терминалка пишет всякую фигню в базу. От терминалки юзера не хотят отказываться, придётся пока это поле "@" пока не трогать. Поставил в начале базы новые типы полей и все вьювера перестали работать. Нечего юзерам лазить по базам.

Haz: Andrey пишет: От терминалки юзера не хотят отказываться, придётся пока это поле "@" пока не трогать. Перекомпилируй под харбур и все, можешь трогать. Все же в харбур более адекватная работа с этими полями.

Andrey: Haz пишет: Перекомпилируй под харбур и все, можешь трогать. Все же в харбур более адекватная работа с этими полями. Да уже не хочется заморачиваться с терминалкой. Заканчиваю перевод проекта на МиниГуи, а старый проект хочу сворачивать.

Andrey: AADD( aDbf , {"DT_ADD" ,"T", 8, 0 } ) // RDD-TimeStamp дата+время+миллисекунды Пишу в поле для теста :[pre2] t1 := hb_DateTime() t2 := hb_NtoT( hb_TtoN( t1 ) - nI * 100 ) ? "t1=",t1, "t2=",t2, Valtype(t2) (TEMPDBF)->DT_ADD := t2 // дату+время вставки записи[/pre2] В отладке так: [pre2] t1= 2018-09-27 22:37:03.755 t2= 2018-06-19 22:37:03.755 T t1= 2018-09-27 22:37:03.774 t2= 2018-03-11 22:37:03.774 T t1= 2018-09-27 22:37:03.792 t2= 2017-12-01 22:37:03.792 T t1= 2018-09-27 22:37:03.81 t2= 2017-08-23 22:37:03.81 T t1= 2018-09-27 22:37:03.828 t2= 2017-05-15 22:37:03.828 T [/pre2] В базе в поле DT_ADD:[pre2] 27.09.2018 22:37:03.774 27.09.2018 22:37:03.792 27.09.2018 22:37:03.810 27.09.2018 22:37:03.828 [/pre2] Чудеса ?

SergKis: Andrey пишет Чудеса ? Не знаю, но догадываюсь как ты их творишь.[pre2] t1 := hb_DateTime() t2 := hb_NtoT( hb_TtoN( t1 ) - nI * 100 ) (TEMPDBF)->DT_DEL := t1 (TEMPDBF)->DT_REST := t2 dbSkip(0) ? "t1=",t1, "t2=",t2, 'DT_DEL=',(TEMPDBF)->DT_DEL,'DT_REST',(TEMPDBF)->DT_REST результат t1= 2018-09-28 05:41:42.659 t2= 2018-06-20 05:41:42.659 DT_DEL= 2018-09-28 05:41:42.659 DT_REST= 2018-06-20 05:41:42.659 t1= 2018-09-28 05:41:42.675 t2= 2018-03-12 05:41:42.675 DT_DEL= 2018-09-28 05:41:42.675 DT_REST= 2018-03-12 05:41:42.675 t1= 2018-09-28 05:41:42.675 t2= 2017-12-02 05:41:42.675 DT_DEL= 2018-09-28 05:41:42.675 DT_REST= 2017-12-02 05:41:42.675 t1= 2018-09-28 05:41:42.675 t2= 2017-08-24 05:41:42.675 DT_DEL= 2018-09-28 05:41:42.675 DT_REST= 2017-08-24 05:41:42.675 t1= 2018-09-28 05:41:42.691 t2= 2017-05-16 05:41:42.691 DT_DEL= 2018-09-28 05:41:42.691 DT_REST= 2017-05-16 05:41:42.691 ... [/pre2]

Pasha: Andrey пишет: Чудеса ? А в чем прикол, кроме нехватки одной строки ? Или это шарада типа "Найди 10 различий" ?

SergKis: Pasha пишет А в чем прикол, кроме нехватки одной строки ? Или это шарада типа "Найди 10 различий" ? Просто Андрей, как всегда, просмотрел, что после его команд, стоит (TEMPDBF)->DT_ADD := (TEMPDBF)->TS которая переносит значение из поля '=' ( TS ) в поле DT_ADD. у меня есть вариант prg файла

SergKis: PS А хотел он заполнить DT_ADD более ранними значениями TimeStamp

Pasha: Да там странный код какой-то. От даты зачем-то отнимается большое количество дней (если nI - целое, а там фиг его знает). Это можно сделать проще: Вместо: hb_NtoT( hb_TtoN( t1 ) - nI * 100 ) можно сделать просто: t1 - nI * 100 поскольку тип TimeStamp - это просто double, где целая часть - дата, а дробная - время. Ну и наверное что-то еще перепутано с переменными, поскольку DT_ADD получает значение t1.

SergKis: Pasha пишет Ну и наверное что-то еще перепутано с переменными, поскольку DT_ADD получает значение t1 Путаницы нет, идет добавление записей в тест. таблицу ("мусорные" значения) с полями +,=,^ t1 := hb_DateTime(), в поле DT_ADD пишет t2, а следом идет запись в DT_ADD из поля TS (тип =, rdd заполнение ) т.е. значение t1 и rdd одинаковые, что логично

Pasha: В коде этого же нет, а я увы не телепат. Если так, то все понятно, все логично

Andrey: SergKis пишет: Просто Андрей, как всегда, просмотрел, что после его команд, стоит (TEMPDBF)->DT_ADD := (TEMPDBF)->TS которая переносит значение из поля '=' ( TS ) в поле DT_ADD. Как всегда Спасибо !

Andrey: Можно ли базу Харбора с новыми полями: + AutoInc 4 Auto increment = ModTime 8 Last modified date & time of this record ^ RowVers 8 Row version number; modification count of this record @ DayTime 8 Date & Time открыть через ADS или локальный клиент ADS ? Сразу возникает вопрос зачем ? А чтобы другой программист мог при логиниться к базе и выбрать нужные записи.

Pasha: Открываем advantage.chm (у меня нашелся для ads 11), ищем раздел DBF Field Types and Specifications там упоминается поля типа AutoInc, TimeStamp RowVer, ModTime похоже нет. Может в более поздних версиях и есть, надо смотреть.

Dima: http://devzone.advantagedatabase.com/dz/webhelp/Advantage12/index.html?master_dbf_field_types_and_specifications.htm

Haz: Эти поля в полном составе есть только в нативном формате ADS , т.е в ADT А чтобы другой программист мог при логиниться к базе и выбрать нужные записи. другой программист может логиниться и выбирать через DBDCDX , и если нужно , то результат писать в свой ADS . Вобщем проблемы не вижу при работе в харбуре. Если речь идет о доступе из другого языка программирования к расширенным типам полей DBF, то у меня сомнения что это вообще возможно.

Andrey: Haz пишет: другой программист может логиниться и выбирать через DBDCDX , и если нужно , то результат писать в свой ADS . Вобщем проблемы не вижу Другой программист на Дельфи работает. Вот и хочет получить доступ к моей базе через Дельфи.

Haz: Andrey пишет: Другой программист на Дельфи работает. Вот и хочет получить доступ к моей базе через Дельфи. Скорее всего пусть забудет об этой идее , вопрос не в ADS а в том что RDD в дельфи скорее всего таких типов не знает в DBF

Haz: Андрей , если бы твоя база была в ADT , то все получилось бы. Если базы не на теробайты, то проще сделать конвертор DBF->ADT а к ADT дельфист легко цепанется через свой ADS

Pasha: Насколько я помню, для Delphi используется клиент от Extend Systems, или кто там его купил-перекупил, наследник TDataSet Так что сами разработчики поддержку своих же типов данных должны были сделать. Другой вопрос, что не все типы данных поддерживает сам Ads

Haz: Pasha пишет: Так что сами разработчики поддержку своих же типов данных должны были сделать. Другой вопрос, что не все типы данных поддерживает сам Ads Так и я об этом же, нативный формат ADS поддерживает все эти типы и компонента доступа к ADS из Delphi соответственно их тоже поймет, но ... в НАТИВНОМ формате ( ADT ) В спецификации DBF от ADS эти поля не поддерживаются полностью ( ModTime и RowVersion не заявлены ) . Это не значит, что вывалит с ошибкой , но и не гарантирует правильное чтение данных . В случае с DBF нужно пробовать ... , а в случае с ADT уже можно работать. Точно сработает если конвертировать средствами харбур базу из DBF в ADT и рыть эту ADT из Delphi

Andrey: Haz пишет: Скорее всего пусть забудет об этой идее , вопрос не в ADS а в том что RDD в дельфи скорее всего таких типов не знает в DBF Haz пишет: Если базы не на теробайты, то проще сделать конвертор DBF->ADT а к ADT дельфист легко цепанется через свой ADS Т.е. совместный доступ сразу из Харбора и Дельфи не возможен ? А то Дельфист службу хочет ваять и передавать мои записи куда то через шлюз в другую прогу.

SergKis: Andrey пишет А то Дельфист службу хочет ваять и передавать мои записи куда то через шлюз в другую прогу. Ты уверен, что надо напрямую пускать стороннего пользователя в данные клиента из ЧУЖОЙ проги ? Могут возникнуть нюансы. Игорь, по мне, верно предлагает решение export\import

Haz: Andrey пишет: Т.е. совместный доступ сразу из Харбора и Дельфи не возможен Возможен, при стандартных полях, ты же решил использовать расширенные. Отсюда и нюансы

Andrey: SergKis пишет: Ты уверен, что надо напрямую пускать стороннего пользователя в данные клиента из ЧУЖОЙ проги ? Могут возникнуть нюансы. Игорь, по мне, верно предлагает решение export\import Да я предлагал делать выгрузку из своей базы в обычный DBF. Отказался программист, он решил что сам сделает службу, подключаясь напрямую к базе. Там у руководства своё видение, пускай тогда пробует. Посмотрим что будет. Хороший полигон для проверки.

SergKis: Andrey пишет Посмотрим что будет. Хороший полигон для проверки. Если у тебя в базе не деньги, то ... пробовать, можно. Но как отследишь "чужую" модификацию, или слив данных на сторону ?

Andrey: SergKis пишет: Если у тебя в базе не деньги, то ... пробовать, можно. В том то и дело, что в базе приход оплаты абонентов. Я с себя всякую ответственность снимаю, захотело руководство и пусть у них голова болит...

krutoff: Андрей, я когда-то на Дельфи применял компонент VKDBF http://vlad-karpov.narod.ru/Components.html#VK%20DBF Он поддерживает 60 разширеных типов полей. CDX-индексы тоже. Глянь, может вашему дельфисту сгодится. Я одновременно работал с Делфи и Харбором с одной базой dbf-файлов.

Andrey: krutoff пишет: Я одновременно работал с Делфи и Харбором с одной базой dbf-файлов. Спасибо БОЛЬШОЕ !

Andrey: Pasha пишет: Поле AutoInc не предназначено для изменения. Оно заполняется автоматически при добавлении записи. При попытке что-либо записать в поле возникает ошибка EDBF_DATATYPE Если есть такое поле в базе, то при переносе в новую базу значение таких полей автоматом переноситься из старой базы ? Сделал небольшой тест, вроде переносятся. Хочется точно знать.

Haz: Andrey пишет: Хочется точно знать Не переносятся! Не должны. Заполняются автоматом в новой базе в порядке добавления записей. Переносить умеют только системы бекап/ресторе.

Andrey: Haz пишет: Не переносятся! Не должны. Беру утилиту dbedit, открываю уже созданную базу, удаляю все записи AutoInc до 20-29 и после 32, т.е. делаю разрыв нумерации в базе. Потом делаю PACK. Создаю новую базу, добавляю из другой базы (меню: Операция, меню: Добавить из файла) и результат - ВСЕ записи в новой базе !

Haz: Andrey пишет: ВСЕ записи в новой базе ! Могу только поздравить! Видимо счетчик тикает только при dbAppend() Append From и Copy To его не изменяют. Даже не знаю это баг или фича

ZAlex: Andrey пишет: ВСЕ записи в новой базе ! А если в тест добавить добавление нескольких новых записей? Как "ведет" себя поле AutoInc?

Andrey: Haz пишет: Append From и Copy To его не изменяют. Даже не знаю это баг или фича Нужно тогда у Паши спросить, как он в своей утилите DBEDIT копирует записи из другой базы ? ZAlex пишет: А если в тест добавить добавление нескольких новых записей? Как "ведет" себя поле AutoInc? Проверил. Добавляет по счётчику, т.е. если в базе был 34 номер, то следующая запись становиться 35.

SergKis: Andrey пишет Проверил. Добавляет по счётчику Небольшая правка Tsb_Basic\demo.prg показывает как работает AutoInc [pre2] FUNCTION UseOpenBase() ... IF ( lDbfNo := ! File( cDbf+'.dbf' ) ) AAdd( aStr, { 'F0', '+', 4, 0 } ) AAdd( aStr, { 'F1', 'D', 8, 0 } ) AAdd( aStr, { 'F2', 'C', 60, 0 } ) AAdd( aStr, { 'F3', 'N', 10, 2 } ) AAdd( aStr, { 'F4', 'L', 1, 0 } ) dbCreate( cDbf, aStr ) ENDIF ... WHILE TEST->( RecCount() ) < 20 // 10 TEST->( dbAppend() ) TEST->F1 := Date() + n++ ... USE ( cDbf ) ALIAS "TEST" SHARED NEW OrdSetFocus('NN') GO TOP COPY TO ( '_1' ) FOR ','+hb_ntos(RecNo())+',' $ ',3,5,7,11,15,' GO TOP COPY TO ( '_2' ) FOR ','+hb_ntos(RecNo())+',' $ ',2,4,6,10,14,' GO TOP USE ( '_2' ) ALIAS T1 NEW GO TOP ? '_2.dbf', T1->( LastRec() ) WHILE ! EOF() ? RecNo(), T1->F0, T1->F1 SKIP ENDDO USE ? USE ( '_1' ) ALIAS T1 NEW GO TOP ? '_1.dbf', T1->( LastRec() ) WHILE ! EOF() ? RecNo(), T1->F0, T1->F1 SKIP ENDDO dbAppend() dbSkip(0) APPEND FROM ( '_2' ) dbGoBottom() dbAppend() GO TOP ? '_1.dbf+_2.dbf', T1->( LastRec() ) WHILE ! EOF() ? RecNo(), T1->F0, T1->F1, iif(empty(T1->F1), 'New', '' ) SKIP ENDDO USE SELECT TEST ... Результат: _2.dbf 5 1 2 24.01.2019 2 4 26.01.2019 3 6 28.01.2019 4 10 01.02.2019 5 14 05.02.2019 _1.dbf 5 1 3 25.01.2019 2 5 27.01.2019 3 7 29.01.2019 4 11 02.02.2019 5 15 06.02.2019 _1.dbf+_2.dbf 12 1 3 25.01.2019 '' 2 5 27.01.2019 '' 3 7 29.01.2019 '' 4 11 02.02.2019 '' 5 15 06.02.2019 '' 6 21 . . New 7 22 24.01.2019 '' 8 23 26.01.2019 '' 9 24 28.01.2019 '' 10 25 01.02.2019 '' 11 26 05.02.2019 '' 12 27 . . New [/pre2]

Haz: SergKis пишет: как работает AutoInc Тоесть. При Copy to сохраняется значение, в остальных переприсввивание по счётчику

Dima: Andrey пишет: Нужно тогда у Паши спросить, как он в своей утилите DBEDIT копирует записи из другой базы ? Думаю по тому же алгоритму как и в LETO Backup . Сырцы есть , сам глянь. PS Тема если что http://clipper.borda.ru/?1-7-0-00000010-000-10001-0-1330362141

SergKis: Haz пишет Тоесть. При Copy to сохраняется значение, в остальных переприсввивание по счётчику Да, при copy to сохраняется значение, при dbcreate счетчик с 0. dbappend, append from увеличивают счетчик в заголовке dbf. dbdelete + pack меняют только lastrec()

Andrey: Всем привет ! Вот нашёл в инете: Data File Header Structure for the dBASE Version 7 Table File https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm Структура DBF-файла http://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTM А для Харбора есть подобные описание ? Может кто встречал. И что за тип полей OLE ? Кто нибудь с ним работал ? И ещё вопрос, можно в Харборе определить версию DBF-файла ? У многих просмоторщиков есть такая функция.

Pasha: dBASE Version 7 - это продукт еще из прошлого века, со своим форматом, там имя поля может быть до 32-х символов. Харбор его не поддерживает. Что касается номера версии dbf - это сигнатура файла, его первый байт, то стандартными средствами харбора его считать нельзя

rvu: Pasha пишет: стандартными средствами харбора его считать нельзя Любой файл можно прочитать. Просто как файл, не dbf.

Pasha: Стандарт - это получить средствами rdd. Все остальное - неформат. Например, в pArea есть структура dbfHeader, в которой этот байт уже есть, и файл читать не надо

SergKis: rvu пишет Любой файл можно прочитать. Просто как файл, не dbf Не все так просто. Например установка cdp в dbf не держится, точно уже не помню, но после закрытия dbf терялась. Пробовали устанавливать, правда, еще на hb 2.0 потом забросили с cdp. Ф-я была такая[pre2] HB_FUNC( DBSETCDP ) { AREAP pArea = hb_rddGetCurrentWorkAreaPointer(); if( pArea && ISCHAR(1) ) { char * pCdp = hb_parc(1); if( pCdp ) pArea->cdPage = hb_cdpFind( (char *) pCdp ); } } [/pre2]

Andrey: Всё понятно, что прочитать какой формат DBF - это сложно. А есть список какие типы DBF может читать Харбор ? Я так понял что не все DBF можно открыть Харбором.

Andrey: Беру поле базы "T" и загоняю в System.Clipboard := cValToChar(oBrw:GetValue(nCol)) Как эту строку записать в другое поле "T" ? Пробовал так, что то не та функция:[pre2] xWrt := HB_STRTOTS( System.Clipboard ) oBrw:SetValue(nCol, xWrt)[/pre2]

Andrey: Ответ получил, xWrt := hb_CToT( System.Clipboard )

Andrey: Есть такие преобразования поля: [pre2] tRecno := SKLAD->TSZ // тип поля "=", RDD-TimeStamp дата+время+миллисекунды ? HB_TSTOSTR( tRecno ) , '"' + VALTYPE( HB_TSTOSTR( tRecno ) ) + '"' // "C" 2021-07-03 22:31:58.984 ? HB_TTOC( tRecno ) , '"' + VALTYPE( HB_TTOC( tRecno ) ) + '"' // "C" 03.07.21 22:31:58.984 ? HB_TTOD( tRecno ) , '"' + VALTYPE( HB_TTOD( tRecno ) ) + '"' // "D" 03.07.2021 ? HB_TTON( tRecno ) , '"' + VALTYPE( HB_TTON( tRecno ) ) + '"' // "N" 2459399.94 ? HB_TTOS( tRecno ) , '"' + VALTYPE( HB_TTOS( tRecno ) ) + '"' // "C" 20210703223158984 cDT := HB_TSTOSTR( tRecno ) ? HB_STRTOTS( cDT ) , '"' + VALTYPE( HB_STRTOTS( cDT ) ) + '"' // "T" 2021-07-03 22:31:58.699 ? HB_CToT(cDT) , '"' + VALTYPE( HB_CToT(cDT) ) + '"' // "T" 22:33:09.809 [/pre2] А как можно получить только время - 22:31:58.984 - строку ?

Pasha: А как можно получить только время - 22:31:58.984 - строку ? Так ответ же сидит прямо в вопросе. Через substr ? substr(hb_ttoc(tRecno), 10)

Haz: Andrey пишет: как можно получить только время посмотреть параметры hb_ttoc() и выбрать нужный шаблон

SergKis: Andrey пишет А как можно получить только время - 22:31:58.984 - строку ? cTime := hb_TtoC( tDateTime ) cTime := Subs( cTime, At(" ", cTime) + 1 ) или cTime := Subs(HB_TSTOSTR( tDateTime ), 12 ) cTime := Subs(HB_TSTOSTR( tDateTime ), 12, 8 ) или cTm1 := cTm2 := "" tDtm := hb_DateTime() tUtc := hb_TSToUTC( tDtm ) HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) HB_TTOD( tUtc, @cTm2, "hh:mm:ss" )

Andrey: Pasha пишет: Так ответ же сидит прямо в вопросе. Через substr ? substr(hb_ttoc(tRecno), 10) Ну это понятно, что можно через substr(), хотелось как правильней. SergKis пишет: cTm1 := cTm2 := "" tDtm := hb_DateTime() tUtc := hb_TSToUTC( tDtm ) HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) HB_TTOD( tUtc, @cTm2, "hh:mm:ss" ) Спасибо !

Andrey: Что-то не идёт....[pre2] cTm1 := cTm2 := "" ? 8, tDtm := HB_DATETIME() , '"' + VALTYPE( tDtm ) + '"' ? 9, tUtc := hb_TSToUTC( tDtm ) , '"' + VALTYPE( tUtc ) + '"' ? 10, HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) , '"' + VALTYPE( HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) ) + '"' ? 11, HB_TTOD( tUtc, @cTm2, "hh:mm:ss" ) , '"' + VALTYPE( HB_TTOD( tUtc, @cTm2, "hh:mm:ss" ) ) + '"' 8 2021-07-18 15:30:45.254 "T" 9 2021-07-18 12:30:45.254 "T" 10 18.07.2021 "D" 11 18.07.2021 "D" [/pre2]

Dima: Лови [pre2] hb_Regex( "([\d+]{2}[:][\d+]{2}[:][\d+]{2}[.][\d+]{3})" , hb_ttoc(HB_DATETIME()),.f.)[1] [/pre2]

Andrey: Dima пишет: Лови Спасибо большое ! Но это уже извращение... Хочется понять, какие есть функции в Харборе для этих операций ?

SergKis: Andrey [pre2] cTm1 := cTm2 := "" tDtm := hb_DateTime() tUtc := hb_TSToUTC( tDtm ) HB_TTOD( tDtm, @cTm1, "hh:mm:ss" ) HB_TTOD( tUtc, @cTm2, "hh:mm:ss" ) s_nHour := Val(cTm1) - Val(cTm2) ? procname() ? tDtm, cTm1 ? tUtc, cTm2 ? результат GMT2UTC 2021-07-18 16:09:11.557 16:09:11 2021-07-18 13:09:11.557 13:09:11 [/pre2]

Andrey: SergKis пишет: результат Ступил... Но мне нужно время полностью 16:09:11.557 ! Как тогда указать формат ?

SergKis: Andrey используй короткое cTime := Subs(HB_TSTOSTR( tDateTime ), 12 ) формат hh:mm:ss.fff

Andrey: SergKis пишет: формат hh:mm:ss.fff Спасибо БОЛЬШОЕ ! По инету искал и не нашёл, всякую фигню поиск предлагает.

Andrey: А как допустим выбрать все записи по определённой дате по базе, по полю типа "Т" ? Допустим есть база с полем SKLAD->TSZ, нужно выбрать все записи за текущую дату. [pre2]dDate := DATE() cDate := ???? cFilter := "TSZ == " + cDate + ".AND. !DELETED()" SET FILTER TO &cFilter [/pre2]

SergKis: Andrey см. http://clipper.borda.ru/?1-6-0-00000001-000-140-0-1626772941 пост N: 1708

Andrey: Так правильно ? cFilter := HB_CTOT( SKLAD->TSZ, "YYYYMMDD" ) + "==" + DTOS(dDate) + ".AND. !DELETED()"

SergKis: Andrey пишет Так правильно ? Если работает то, да Еще такой вариант cDat := HB_DTOC(Date(), 'YYYY-MM-DD') cFilter := '!DELETED() .AND. "'+cDat+'" $ HB_TSTOSTR( SKLAD->TSZ)'

Петр: Andrey пишет: Так правильно ? cFilter := HB_CTOT( SKLAD->TSZ, " Нет. Если я правильно понял у SKLAD->TSZ тип "T", а HB_CTOT ожидает принять в качестве первого аргумента строку. можно так hb_LeftEq( HB_TTOS(SKLAD->TSZ), DTOS(dDate) ) или так Empty( Int( SKLAD->TSZ - dDate ) ) или через HB_TTOC и т.п.

Andrey: Вообще то по датам и даже так ищёт: cFilter := "(TSZ>=CTOD('10.09.21').AND.TSZ<=CTOD('25.09.21') ).AND.!Deleted()"

SergKis: Andrey пишетпо датам и даже так ищёт тогда проще можно SET DELETED ON SET FILTER TO TSZ >= 0d20210910 .AND. TSZ <= 0d20210925 GO TOP ... SET DELETED OFF

Петр: Andrey пишет: Но мне нужно время полностью 16:09:11.557 ! Как тогда указать формат ? "hh:mm:ss.fff" ? dDate := hb_TToD( hb_DateTime(), @cTime, "hh:mm:ss.fff" ) ? hb_DToC(dDate, 'YYYY-MM-DD'), cTime P.S. Я знаю, SergKis написал уже, но просто хотелось еще раз привлечь внимание Андрея к функции hb_TToD. Очень удобна для разбивки переменной (поля) DateTime на Date и Time , с последующим изменением в DATEPICKER и TIMEPICKER (MiniGUI).

Петр: Andrey пишет: Вообще то по датам и даже так ищёт Это понятно When date and timestamp values are used in <, <=, >, >=, = operations then VM compares only date part in both values. SergKis пишет: тогда проще можно SET DELETED ON SET FILTER TO TSZ >= 0d20210910 .AND. TSZ <= 0d20210925 Да, но учтите, что Андрею скорее всего нужно, наверное, SET DELETED ON SET FILTER TO TSZ >= dDate1 .AND. TSZ <= dDate2 или SET FILTER TO TSZ >= tDateTime1 .AND. TSZ <= dDateTime2

SergKis: Петр пишет что Андрею скорее всего нужно, наверное, SET DELETED ON SET FILTER TO TSZ >= dDate1 .AND. TSZ <= dDate1 Ему нужно вариант от составленной строки SET FILTER TO &('TSZ >= 0d20210910 .AND. TSZ <= 0d20210925') Он пишет выше везде cFilter := "..." и получить 'TSZ >= 0d'+DtoS(dDate1) и.т.д. проще

Петр: SergKis пишет: Ему нужно вариант от составленной строки Возможно. PUBLIC dDate1, dDate2 SET FILTER TO &('TSZ >= dDate1 .AND. TSZ <= dDate2') - тоже ведь не сложно? Но это детали реализации и предпочтений, в общем - вкусовщина.

SergKis: Петр пишет тоже ведь не сложно? Дело не в этом (переменные лучше PRIVATE вместо PUBLIC), а в том что строку фильтра можно сохранить в базе (там не только период но др. данные запроса), обозвав его "Отчет за I квартал ..." и таких строк\отчетов может быть много (создавать их может сам клиент или админ, гл. бух, "начальник транспортного цеха" и т.д.). Использовать хоть удаленный клиент и длительное время. PS В LetoDb строка фильтра должна быть в таком виде, как у Андрея, оптимизированный фильтр. В LetoDbf, кроме такого фильтра, есть механизм переноса PRIVATE, PUBLIC переменных на сторону сервера для исп. в выражении фильтра.

Andrey: Спасибо вам БОЛЬШОЕ !

Andrey: tDateTime := hb_DateTime() А как сделать пустую tDateTime ? Для даты есть функция CTOD(""), а здесь как ? И как проверить на пустое значение ? Функция Empty(tDateTime) будет работать ?

Петр: Andrey пишет: А как сделать пустую tDateTime ? Для даты есть функция CTOD(""), а здесь как ? hb_CToT("") Andrey пишет: Функция Empty(tDateTime) будет работать ? Да. Empty() работает для всех скалярных типов.

Andrey: Петр СПАСИБО БОЛЬШОЕ !

Sergy: Andrey пишет: Для даты есть функция CTOD(""), Чем не устраивает нулевое значение даты 0d0 ?

Andrey: Вопрос был - А как сделать пустую tDateTime ?

Pasha: кроме hb_ctot("") есть еще hb_datetime(0, 0, 0, 0, 0, 0, 0)



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