Форум » [x]Harbour » Снова EXCEL » Ответить

Снова EXCEL

Dima: Ранее с Excel из Harbour ни когда не работал. Поставили тут задачу. У некоторых поставщиков есть определенные формы заказов. Набраны они в Excel. Сейчас народ руками заполняет эти формы и шлет по электронке поставщикам. Задача сводится к тому что бы в этих формах находить нужные коды товара и в нужной ячейке проставлять заказ. Может ткнет кто носом с чего начать что бы не напороться на грабли. Спасибо Сами формы тут http://zalil.ru/33279066

Ответов - 300, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 All

Pasha: Softlog86 пишет: Символ собаки "@" - это текстовый ? Если можно - сообщите какие ещё команды управления форматами . Мне нужнее всего текстовый и дата Да, текстовый. А насчет остальных форматов - сделайте запись макросов, и гляньте сами. У меня на работе и экселя то нет, чтобы посмотреть :)

Softlog86: Andrey Пробовал ! Пробел не решает сути вопроса - Эксель автоматом рубит лидирующий ноль если в строке только цифры . Так что " 0123" всё-равно получается как "123" . Паша верно подсказал - теперь всё работает как надо !

Dima: Вопросец назрел. Excel уже открыт и в нем загружена куча документов. Необходимо средствами Harbour создать документ Excel , заполнить его , сохранить и выйти. Как при этом оставить открытыми ранее документы , ведь по команде oExcel:Quit() закроются все. Как корректно это реализовать ?


Haz: Dima пишет: ведь по команде oExcel:Quit() закроются все Дима, открывай 2 объекта в примере OExcelTwo останется открыт : oExcel := CreateObject( "Excel.Application" ) oExcelTwo := CreateObject( "Excel.Application" ) oExcel:WorkBooks:Add() oExcelTwo:WorkBooks:Add() oExcelTwo:Visible := .T. oExcel:Visible := .T. oExcel:Quit()

Dima: Haz Да точно это я тормознул что то. Сенкс.

Dima: Хотя........ Я делал вот так [pre2] proc main private oExcel if Start_Excel() oExcel:WorkBooks:Add() oExcel:Visible := .t. oExcel:Quit() endif return ************** func Start_Excel() Local Res:=.f. #ifndef __XHARBOUR__ #xcommand TRY => BEGIN SEQUENCE WITH {|e| Break( e )} #xcommand CATCH [<!oErr!>] => RECOVER [USING <oErr>] <-oErr-> #endif TRY oExcel := GetActiveObject( "Excel.Application" ) oExcel:DisplayAlerts:=.f. Res:=.t. CATCH Res:=.f. TRY oExcel := CreateObject( "Excel.Application" ) Res:=.t. CATCH Res:=.f. END END Return Res [/pre2] В этом случае закрывается все в Excel Понял в чем дело.....надо переделать слегка Start_Excel() что бы понять делать ли при выходе из проги oExcel:Quit()

Haz: я делаю примерно так же но через ссылку типа того: Func Main() local oExcel StartExcel( @oExcel ) IF Valtype(oExcel) == "O" .... ELSE ... END RETURN NIL В общем смысл в том что в стартексель передаем ссылку на любую переменную, и она становится объектом ексель и какой объект закрывать вопросов не вызывает )

Dima: Haz Это понятно. А мой косяк был в том что использовал уже существующий объект EXCEL , поэтому по oExcel:Quit() все и закрывалось

Sergy: Дабы не плодить новых тем, спрошу здесь. Название темы подходящее. Программа на Harbour формирует отчет в формате XLS методом OLE. Отчет сформирован, сохранен в локальной папке, осталось его открыть. Раньше не парился, делал RUN("excel /e "+cXlsName) и все дела. Все неплохо, но если путь к Excel на машине не прописан - разумеется облом. Нужно либо прописывать путь, либо кидать батник excel.bat, содержащий строку запуска в папку с программой. Захотелось сделать все красиво и элегантно, (как сам Harbour:) ). Пробовал: 1) Создание Excel-объекта с открытием нужного файла - проблема оказалась в том, что после отработки последней строки типа oExcel.WindowState := Maximized управление передается назад программе. А она должна удалить xls файл и локальной папки. Соотв. пока Excel не "отпустит" файл - ничего не выходит. 2) Делал RUN("start /w "+xlsName) - облом на длинных именах, даже помещенных в двойные кавычки. Удивлен. 3) Пока остановился на RUN('cmd /c "'+cXlsName+'"') - и длинные имена понимает и путь к самому Excel прописывать не требуется. Но вот какой вопрос возник: если юзер УЖЕ РАБОТАЕТ с Excel (например, с другим документом) и из Harbour-программы вызывает этот отчет - он формируется, открывается и... сразу управление возвращается программе. Та пытается удалить временный файл с отчетом - разумеется облом, тк он еще открыт. Какие могут быть варианты? Пытаться зациклить программу "по кругу", пока файл можно будет удалить - мне кажется не совсем "правильным" способом. К тому-же так вышло, что создание и удаление временных файлов сосредоточено в одном месте, а вызов и обработка формата Excel - в другом. Если Excel-модуль будет пытаться удалить файл, то придется в вызывающем коде тоже городить огород. Кроме этого, есть часть отчетов, которые не должны быть удалены. Модуль формирования Excel отчетов об этом не в курсе. Подскажите плиз элегантное решение.

petr707: Можно создать "очередь" - список файлов, заявленных на удаление. Добавление в список - в одном месте кода, удаление файлов по списку можно позже и в любом другом месте кода. В рамках одного экземпляра программы - для очереди можно взять массив, для разных - таблицу. При попытке удаления одного файла - нужно проверить возможность этого: файл есть и можно открыть (и закрыть) файл XLS монопольно - fopen(f_name,FO_EXCLUSIVE) Для открытия XLS файлов __RUN("start "+f_name)

Sergy: Да, про FOPEN() как-то не подумал - СПАСИБО! Нужно будет сделать. А то уж шальные мысли в голову лезли - пытаться переименовать... По поводу "start" - только у меня эта команда тупо игнорирует длинные имена файлов? Вместо запуска Экселя на 'start "d:\dir\some long name file.xls"' открывает консольное окно (Microsoft Corporation...) и ждет команд... А по запуску Excel - запустить, когда вернется управление - лучшего решения, чем зациклить пока не получится открыть монопольно, нет ?

nick_mi: Ну если это Harbour, открыть и показать пользователю через OLE ( CreateObject("Excel.Application") ) и проверять например, получая какую-нибудь ячейку. Если это не объект, идти дальше работать

petr707: Фишка в том, что запуск __RUN("start "+xls) открывает окно EXcel, но Harbour-программа не ждет закрытия окна Excel, оно живет независимо и отдельно (похоже, так устроен вызов Win Gui приложений) а программа пилит дальше. Можно, если надо, определить через какой-то момент - запустился Excel или нет. Поэтому - не нужно сразу удалять файл и не нужно ничего ждать в цикле. пример - открывается 5 окон XLS Proc main() Local i,f_name REQUEST HB_LANG_RU866 HB_LangSelect( "RU866" ) REQUEST HB_CODEPAGE_RU866 HB_CDPSELECT( "RU866" ) for i=1 to 5 f_name := "_t_это_пример_номер_"+alltrim(str(i))+".xls" copy file ("test.xls") to (f_name) __run("start "+f_name) next i ? "Press any key" inkey(10) return

nick_mi: Но ведь Sergy писал Но вот какой вопрос возник: если юзер УЖЕ РАБОТАЕТ с Excel (например, с другим документом) и из Harbour-программы вызывает этот отчет - он формируется, открывается и... сразу управление возвращается программе. Та пытается удалить временный файл с отчетом - разумеется облом, тк он еще открыт. т.е. по идее ему нужно стоять и ждать, пока не закончится EXCEL. А вообще-то пусть уже он решает, наше дело предложить решение

PSP: Можно очищать папку с временными файлами при старте программы. В этот момент все они обычно уже не нужны. Но, если какой-то будет отрыт другим приложением, - ничего страшного, пусть остается. Удалится в следующий раз. Вот, к примеру, во временной папке пользователя в винде таких "нужных" файлов иногда десятки тысяч. И ничего, работает... )))

Dima: PSP пишет: Можно очищать папку с временными файлами при старте программы То же так делаю

Sergy: nick_mi пишет: т.е. по идее ему нужно стоять и ждать, пока не закончится EXCEL. Вопрос возникает, только если Excel был запущен раньше, чем сформирован отчет: управление сразу возвращается в программу.

Sergy: PSP пишет: Можно очищать папку с временными файлами при старте программы. В этот момент все они обычно уже не нужны. Но, если какой-то будет отрыт другим приложением, - ничего страшного, пусть остается. Удалится в следующий раз. Вот, к примеру, во временной папке пользователя в винде таких "нужных" файлов иногда десятки тысяч. И ничего, работает... ))) Согласен. Сам так делаю. Но захотелось красивого решения. Пока остановился на вызове через OLE с немедленной передачей управления назад. Это чтобы не гадать вернется/не вернется. А после возврата программа в цикле с интервалом в полсекунды пытается открыть файл в режиме FO_EXCLUSIVE. Как только открылся - значит работа с файлом завершена, а закрыл юзер Excel или продолжает в нем работать с другим документом - дело десятое...

nick_mi: Но ведь нужен вариант который будет работать правильно во всех случаях. Можно, конечно проверить, как показано у Dima oExcel := GetActiveObject( "Excel.Application" ) и в зависимости от этого выпускать или Run () или oExcel := CreateObject( "Excel.Application" ) и выполнять проверку, так как я писал выше правда, в этом случае тоже цикл, но только не FOPEN (cFile,FO_EXCLUSIVE) а на наличие объекта.Пока объект существует, программа будет ждать, независимо от того, запущен ранее EXCEL или запущен из вашей програмы

Sergy: nick_mi пишет: Пока объект существует, программа будет ждать, независимо от того, запущен ранее EXCEL или запущен из вашей програмы Хм. звучит логично. Ну вот допустим, Excel не был запущен. Юзер сформировал отчет, мы создали CreateObject("Excel.Application") и ждем, пока он не исчезнет. Но юзер решил в Экселе с сформированным отчетом открыть еще один документ: например, ему туда нужно вставить данные из только что сформированного отчета. Получается, пока он не закроет все документы и не выйдет из Excel, работать с программой он не сможет? А если ему нужно сформировать другой отчет ? Но ведь нужен вариант который будет работать правильно во всех случаях. Да и потом, не очень понятно, какая разница, чего ожидать в цикле - исчезновения объекта или возможности открыть файл в FO_EXCLUSIVE режиме ?



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