Форум » [x]Harbour » OLE: Сделать DBF из XLS » Ответить

OLE: Сделать DBF из XLS

Лукашевский: Возникла такая вот необходимость... есть у кого рабочий вариант? Нужно ведь проверять все колонки на содержание в первой строке беспробельного латинского наименования, и чтобы ни одно наименование не повторялось, приводить ширину колонки к целочисленной, и наверное кучу ещё тонкостей... И ещё интересно: в Excel 2007 через OLE сохранение в виде DBF-файла сработает, или она там обрублено напрочь - в меню сохранения файла ведь DBF-варианта уже нет...

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

fil: А в чем собственно проблема, отрыть файл XLS через OLE, почитать его в цикле и зписать в DBF ?

Лукашевский: fil пишет: А в чем собственно проблема Проблема далеко не одна, часть из них я указал прямо в своём вопросе, и ещё может быть проблема с записью DBF в Excel 2007, - ты что, только название темы прочёл, а сообщение решил не читать?

Лукашевский: Народ, так что, никто не решал эту проблему? Проблема: нужно закинуть в базу накладную или прайс. Требовать от поставщиков юзверя DBF-файл уже нереально - 2007-й Офис, на который все потихоньку переходят, файлы в DBF-формате не сохраняет, да и не все с этим справляются даже в тех версиях M$ Office (чтобы колонки были целочисленной ширины, и т.п.). Остаётся файл XLS. Принимать его в виде XLS - проверить колонки, сформировать массив - наверное можно, НО работы море всё это реализовывать, при этом всё для принятия DBF-файла в программе уже сделано. Вывод: надо из XLS-файла самому делать DBF-файл, и принимать в базу уже его. Странно, что никто раньше до этого решения не додумался...


Лукашевский: Почти справился с задачей, но возник маленький ньюанс: надо как-то определять, записано в ячейке Excel'я число 40.00 или 40 целое, а как это сделать - не представляю... Подскажите, люди добрые! А ещё бы лучше определять это уже в Harbour'e, когда значение из Excel'я уже прочитано. Но тоже непонятно, как именно это сделать.

Петр: Лукашевский пишет: надо как-то определять, записано в ячейке Excel'я число 40.00 или 40 целое Обьект Range свойство NumberFormat - для 40,00 будет определено как "0.00", для 40 - "0"

Лукашевский: Петр пишет: Обьект Range свойство NumberFormat Спасибо.

Andrey: Лукашевский пишет: Почти справился с задачей А результат покажешь ?

Лукашевский: Andrey пишет: А результат покажешь ? Когда убедюсь, что оно работает :-) Написать мало, отладить надо, однако.

Лукашевский: Очередная проблема: не читается из XLS-файла дата, по крайней мере по oSheet:Cells(y, i):Value Смотрю в XLS-файл - а там все значения дат в этой колонке отображены решётками (########). Хотя когда какая-либо ячейка в этой колонке активна, в строке значения (fx) высвечивается нормальная дата, правильное значение. Смотрю ширину поля: 8. Может быть дело в этом, и надо ставить ширину 10, но мне-то нужно, чтобы функция работала всегда, безотносительно ширины колонки в Excel'e! Опять-таки, каким-то образом сам Excel может читать такие значения - ведь в строке значений они высвечиваются правильно... Что с этим делать - пока не представляю. Может, есть какие-то ещё функции получения значения из ячейки?

Лукашевский: Поставил ширину колонки даты 10, всё отображается без проблем, НО: читаются из ячеек этой колонки всё равно пустые значения!!! Никто с такой фишкой не сталкивался?

Лукашевский: Ещё одна проблема: открываю с помощью WorkBooks:Open() файл, имя которого содержит пробелы. Excel выдаёт ошибку: Excel.Application:WORKBOOKS/14 DISP_E_BADPARAMCOUNT: OPEN что в общем понятно. Непонятно только, как с этим бороться. Пробовал заключать имя файла в кавычки - не помогает...

Pasha: Пробелы в имени тут ни при чем. Скорее всего, имя документа надо преобразовать в кодировку ansi, или указан неверный путь (надо указывать полный путь к файлу)

Лукашевский: Pasha пишет: надо преобразовать в кодировку ansi Да, действительно, проблема была в кодировке... Так что осталась всего одна проблема - дата из Exel'евского файла всегда читается пустая...

Andrey: Потребовалось теперь мне сделать из XLS файл DBF. Структура простая: Текстовое поле, числовое поле (целое), числовое поле (сумма). Как узнать сколько в файле XLS кол-во строк, т.е. как в DBF функция LASTREC() или RecCount() ? И как сделать перебор "полей" XLS - файла ? Кинь пожалуйста пример .... Заранее спасибо !

Pasha: oRange = oExcel:ActiveCell:SpecialCells(xlLastCell) oRange:Row oRange:Column

Andrey: Не совсем понятно !!! Хотелось бы в таком стиле: USE OPLANA NEW nRecKolvo := LASTREC() SELECT OPLATA GOTO TOP FOR nI := 1 TO nRecKolvo GOTO nI // моя обработка // NEXT

Pasha: Смысл в том, что выбирается последняя, т.е. нижняя правая ячейка документа. Затем определяются ее координаты. Это и есть количество строк и столбцов в документе. А затем - традиционный двойной цикл с обходом всех ячек.

Andrey: А как открыть XLS файл, чтоб Екселя на экране не было ? Дайте пожалуйста пример ..... А то я только с Вордом работать умею (чуть-чуть).....

Pasha: Andrey пишет: А как открыть XLS файл, чтоб Екселя на экране не было ? oExcel := TOleAuto():New( "Excel.Application" ) oExcel:Visible := .f. oExcel:Workbooks:Open( cFile, 0 )

Andrey: А как отловить, что файл уже открыт ?

Pasha: Andrey пишет: А как отловить, что файл уже открыт ? Хороший вопрос :) Первая мысль, которая возникла - проверить oExcel:WorkBooks:Count, и пройтись по этой коллекции Но оказалось, что при создании обьекта Excel запускается его новая копия, и Count равно нулю Надо как-то связаться с уже запущенным Excel Кстати, если из документа надо только брать данные, его можно открывать в режиме readonly, это 3-й параметр метода Open

Andrey: Другой вопрос: А как прочитать значение ячейки ? oExcel := TOleAuto():New( "Excel.Application" ) IF Ole2TxtError() != 'S_OK' cError := "Excel файл " + cFileXls + " не могу открыть !" + CLRF + CLRF + "EXCEL OLE ERROR [" + Ole2TxtError() + "]" MsgStop( cError, "Ошибка" ) lOpenXls := .F. ELSE lOpenXls := .T. ENDIF IF lOpenXls // Открыл без ошибок oExcel:Visible := .T. oExcel:Workbooks:Open( cFileXls, 0 ) oSheet := oExcel:Get( "ActiveSheet" ) oRange := oExcel:ActiveCell:SpecialCells( xlLastCell ) nLenRecnoXls := oRange:Row nLenColumnXls := oRange:Column cRecno := AllTrim(Str( nLenRecnoXls )) cColumn := AllTrim(Str( nLenColumnXls )) cRange := '"'+'A'+cRecno+':'+Chr(64+nLenColumnXls)+cRecno+'"' MsgInfo(cRange) cTemp := oSheet:Range( cRange ) MsgInfo( cTemp )

Pasha: Andrey пишет: А как прочитать значение ячейки ? oSheet:Cells(nRow, nCol):Value

a_sidorov: Чтение из активного документа (созданного другим приложением или открытого) TRY oExcel := GetActiveObject( "Excel.Application" ) CATCH TRY oExcel := CreateObject( "Excel.Application" ) CATCH Alert( "ERROR! Excel not avialable. [" + Ole2TxtError()+ "]" ) RETURN END END oExcel:ActiveWorkbook() oAS := oExcel:ActiveSheet() Количество закладок lw:= oExcel:Worksheets():count Нужная закладка lt oAS := oExcel:Worksheets(lt) Примеры чтения из вычисленной программой ячейки schet:=oAS:Range(nc+alltrim(str(num_str,6))):value Tip_s:=Alltrim(HB_ANSITOOEM(oAS:Range(nsc+alltrim(str(num_str,6))):value))

Andrey: Pasha пишет: oSheet:Cells(nRow, nCol):Value Что-то не совсем понятно..... Чему равно nRow, nCol ? Числам ? А где же "A150:B150" ? Или можно использовать 2 варианте ?

Pasha: Это числовой номер строки и колонки Для Cells синтаксис A1 не поддерживается

Andrey: Спасибо ВСЕМ большое за помощь !!!

Andrey: Рано порадовался.... Из памяти не выгружается ЕХСЕЛ... Хотя ставлю при выходе из функции oExcel:Quit() Где собака зарыта ?

Pasha: попробуй так oBook:Close(.f.) // закрытие документа-книги oExcel:Quit()

Andrey: Уф... сделал.... Выкладываю ссылку на готовую программу. Может кому понадобиться.... http://files.mail.ru/YFRFIO Спасибо всем за помощь.....

Oskar_AAA: Добрый день.... если можно выложить исходный код конвертера XLS To DBF буду благодарен... в XLS файле будут объедененные строки (код пункта продажи) далее идут строки код товара (до 8 строк) наименование товара, цена итд... По поводу объединенных строк если можно то поподробнее.... Конвертер из DBF To XLS с Вашей помощью уже сделал. Всем спасибо

Pasha: Oskar_AAA пишет: По поводу объединенных строк если можно то поподробнее.... Чтобы объединить в Excel произвольную область ячеек, надо выдать команды: oRange := oSheet:Range(oSheet:Cells(nRow1, nCol1), oSheet:Cells(nRow2, nCol2)) oRange:Merge()

gustow: Pasha , Оскар про "объединенные строки", наверное (как я понял), спрашивал - "как их обойти?", а не "как их в экселке создать?". Oskar_AAA , загуглил я на "xls to dbf harbour" - вылетело, в частности, на пост из конфы "Harbour Users": http://groups.google.com/group/harbour-users/browse_thread/thread/a7e274f383c77d55 Может, поможет? (при доработке надфилем по месту :) )

Andrey: Oskar_AAA пишет: если можно выложить исходный код конвертера XLS To DBF буду благодарен Я уже сделал 3 программки на Минигуи. С помощью наших гуру... Паши, Филатова и других... Пример выкладываю. Исходник конвертирования тоже выкладываю, там нетрудно понять и переделать на хХарбор. http://files.mail.ru/CP2U1B Я Филатову высылал полные исходники для МиниГуи. И как я вижу по Екселю нужны примеры решения тех или иных проблем. Может выложите кто уже работал готовые решения ? Типа: решение того-то ... исходник...

SADSTAR4: "Ася открыла для себя прокладки Олвейс" а я открыл для себя что под харбором для написания экселовских функций лучше использовать нотацию RC. Например [pre2] //=СЧЁТ(RC[-10]:RC[-1]) //=СУММ(RC[-11]:RC[-2])/RC[-1] //написать формулы k:=len(aRes) ... for i:=1 to 24 //часы суток oSheet:Cells( Row1+i, 1+k+1):Formula:="=СЧЁТ(RC[-"+alltrim(str(k))+"]:RC[-1]" oSheet:Cells( Row1+i, 1+k+2):Formula:="=ОКРУГЛ(СУММ(RC[-"+alltrim(str(k+1))+"]:RC[-2])/RC[-1];0)" next [/pre2] 1-количество непустых ячеек среди К ячеек впереди текущей в текущей строке 2-среднее арифметическое среди вышеуказанных ячеек И никакой возни с преобразованием в буквенное наименование столбцов. P.S. можно оптимизировать - вынести формирование формул за цикл.

Oskar_AAA: Добрый день, коллеги. Спасибо за информацию. Буду изучать. О результатах сообщу. Спасибо.

Oskar_AAA: Андрей, добрый день. У меня нет файла Excel.ch - где его взять. Использую xHarbour Compiler build 1.2.1 (SimpLex) (Rev. 6476)....

Andrey: Oskar_AAA пишет: У меня нет файла Excel.ch - где его взять. Выслал на почту.

Oskar_AAA: Добрый день, вроде получилось... по краней мере на сегодня устраивает. Данные формата Дата пока не пробовал принимать. Всем спасибо.

СевДон: Andrey! Пока я вышел из отпуска твои линки уже не работают... Мож есчо раз выложить эти проги по конвертации?

Andrey: СевДон пишет: Мож есчо раз выложить эти проги по конвертации? Можна.... http://files.mail.ru/8DJQAL Коментарии приветсвуются ...

azoo: А ещё, если не трудно. Или программку прямо в посте написать, чтобы с обменниками не связываться, которые через месяц удаляют файлы.

Dima: azoo пишет: Или программку прямо в посте написать, чтобы с обменниками не связываться, которые через месяц удаляют файлы. По идее можно завести общий почтовый ящик на mail.ru , доступ к нему давать через личные сообщения.

MIKHAIL: azoo пишет: А ещё, если не трудно. Поддерживаю!

MIKHAIL: Dima пишет: По идее можно завести общий почтовый ящик на mail.ru , доступ к нему давать через личные сообщения. Наверное проще яндекс или гугл диск расшареный

Andrey: MIKHAIL пишет: Наверное проще яндекс или гугл диск расшареный Нет, не нужно. Лучше делать типа так, как в другой теме: https://gist.github.com/VerchenkoAG/40c50f644459caa7ce3c И найти можно будет всем и не потеряется. Правда базы куда выкладывать к примеру, не знаю.

Oskar_AAA: Добрый день, Возникла необходимость обработки значения Excel в формате "дата ЧЧ:ММ:СС" и разделить на два поля : формате "D" и формат "С". Как это сделать? Xl_Dat_Upr:=oSheet:Cells(Ni,2):Value возвращает D.... Спасибо...

Dima: Oskar_AAA что вернет ? ? Xl_Dat_Upr

Oskar_AAA: Возвращает тип поля "D"...

Dima: я не про тип set date to german ? hb_datetime() вернет 26.11.15 21:24:30.408 а что вернет EXCEL через олю в переменной Xl_Dat_Upr ?

Oskar_AAA: возвращает 01.10.2015 09:25:31.00 остается конвертировать в нужный тип

Oskar_AAA: Тип поля получается "D", если вывести Xtoc(Xl_dat_Upr) = 01.10.2015 09:25:31.00. B=Xtoc((Xl_dat_Upr) ?b 20151001 показания по времени отсутствуют...?

Dima: Oskar_AAA Попробуй результат загнать в hb_tstostr() или в hb_valtoexp() а после разбери строку как нужно.

Oskar_AAA: Dima что за функция tstostr(), valtoexp()? у меня xharbour 1.2.1 rev.6476

Haz: Oskar_AAA пишет: что за функция tstostr() см ChangeLog http://sourceforge.net/p/xharbour/mailman/message/33552640/ за дату 2015-03-01 15:10

Oskar_AAA: Где скачать hbextern.ch, в версии от 2015-03-01 15:10

Dima: Oskar_AAA пишет: Где скачать hbextern.ch, в версии от 2015-03-01 15:10 http://sourceforge.net/p/xharbour/code/HEAD/tree/trunk/xharbour/include/hbextern.ch PS Боюсь этот CH ни чего не даст. Возможно достаточно там же дернуть сырец HB_TSTOSTR

Oskar_AAA: Dima Спасибо, уже нашел, скопировал, # Include 'Command.Ch' # Include 'Inkey.Ch' # Include 'Dbedit.Ch' # Include 'Setcurs.Ch' # Include 'Excel.Ch' # Include 'Hbgtinfo.Ch' # Include 'Hbextern.Ch' A:=oSheet:Cells(Ni,1):Value ?a ?valtype(a) b=TSTOSTR(a) ?Valtype(b) ?b wait Error: Unresolved external '_HB_FUN_TSTOSTR' referenced from AVTO_002.OBJ как быть?

Dima: Oskar_AAA пишет: как быть? Вот сырец http://sourceforge.net/p/xharbour/code/HEAD/tree/trunk/xharbour/source/rtl/dateshb.c Дерни от туда HB_TSTOSTR и прилинкуй к проге



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