26.07.2011, 12:45 | #1 |
MCITP
|
обрабатывать xls-файл после того как доступ получен
Всем добрый день!
Ax2009 Kernel 5.0.1500.3761 App 5.0.1500.3761 office 2007 Возможно для вопроса необходимо создать отдельную тему, но решил спросить в текущей. Есть файл *.xls. Однако при открытии файла непосредственно Excel выскакивает сообщение, что "Действительный формат отличается от указываемого его расширением ". Если использовать указанную в данной теме строку подключения, то возникает ошибка "Внешняя таблица не имеет предполагаемый формат". Данная тема - это Вспомогательный класс для импорта из Excel через ADO Если прописать строку "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + %1 + ";Extended Properties='HTML Import;HDR=YES;IMEX=1'" То открытие файла происходит корректно ( во всяком случае метод getConnection отрабатывает без ошибок). Но не могу понять, как обрабатывать файл после того как доступ получен. Возможно я пошёл не тем путём. :-( Заранее спасибо за ответы! Последний раз редактировалось GBH; 26.07.2011 в 13:02. |
|
26.07.2011, 15:21 | #2 |
Moderator
|
Читать строка за строкой, поле за полем в цикле. Там же в classDeclaration подробнейшим образом в каментах всё расписано:
Цитата:
#// gl00mie, import data from Excel via ADO, 20061220 -->
#// How to use this class: #// 1. Create class instance, specify filename and (optional) cursor type e.g. #// doc = new ExcelImportADO(strFilename, #adOpenStatic); #// 2. Read names of worksheets present in the file, suppress error messages if necessary #// con = doc.getExcelSheetNames(); #// 3. Specify the name of the worksheet to open ADODB.Recordset on, otherwise the first one will be used #// doc.excelSheetName(conpeek(con,2)); #// 4. Open the file, i.e. open ADODB.Recordset (and ADODB.Connection if it's not opened yet) #// suppress error messages if necessary and check for result: #// if(doc.openFile(false)) ... #// 5. Check if there is a correct number of columns in the Recordset #// if(doc.getFieldsCount() > 7) ... #// 6. Get the total record count if #adOpenStatic cursor type is used #// cnRecords = doc.getRecordCount(); #// 7. Read records in a loop, use indexes (1..n) or field names to identify fields #// By default field values are returned as strings #// int i; #// real r; #// str s; #// while(!doc.eof()) #// { #// i = doc.getFieldValue(1, false); #// s = doc.getFieldValue('stringField'); #// r = doc.getFieldValue('numericField', false); #// doc.moveNext(); #// } #// 8. Cleanup - close ADODB.Recordset and ADODB.Connection #// doc.finalize(); |
|
26.07.2011, 15:59 | #3 |
MCITP
|
Спасибо за ответ!
Но у меня сразу же пункт 2 не отработает, листов-то нет, как я понимаю. Во всяком случае у меня пишет, что листы не найдены. |
|
26.07.2011, 16:11 | #4 |
Moderator
|
Точно у вас файл - .xls? Не .xlsx? Потому что для .xlsx надо не Jet, а ACE: Вспомогательный класс для импорта из Excel через ADO
Показали бы код что ли... |
|
26.07.2011, 16:37 | #5 |
MCITP
|
Да, файл *.xls.
Если использовать ACE то валится с ошибкой ещё при получении доступа "Внешняя таблица не имеет предполагаемый формат". Строка подключения: X++: #localmacro.ADODBExcelConnString "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + %1 + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1'" "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + %1 + ";Extended Properties='HTML Import;HDR=YES;IMEX=1'" #endmacro Если со второй, то возникает ошибка 2 в методе openFile в строчке X++: rstExcel.Open(@"SELECT * FROM [" + strSheetName + @"$]", this.getConnection(), nCursorType); |
|
26.07.2011, 17:02 | #6 |
Moderator
|
Объект '0$' ? Назвали бы лист как-то посолиднее, хотя бы букву добавьте перед нулем...
|
|
26.07.2011, 17:34 | #7 |
MCITP
|
Лист называется корректно, это так определяется
Поэтому я и считаю, что обращаться к листам тут не получится, а вот как я не знаю. Штатное открытие данного файла екселем сразу же выдаёт сообщение "Действительный формат отличается от указываемого его расширением " и выскакивет окошко. После нажатия кнопки "Да", файл открывается, где мы видим нормальное наименование листа. Но, насколько я понимаю, чтобы корректно открыть данный файл происходит какая-то операция, которая позволяет корректно это сделать и в лоб, первой строкой подключения, данный файл не обработать. Вторая строка получает доступ к файлу, но работать с листами не получается. Скорее всего, можно и подключением первой строкой добиться нужного результата, но, к сожалению, я не знаю как(также как и второй строкой подключения обработать файл) . Поэтому надеюсь на совет в какую сторону копать. |
|
26.07.2011, 17:53 | #8 |
Участник
|
А у вас точно файл экселевский?
Может, это обычный текстовый файл с расширением xls? Попробуйте просмотреть его содержимое обычным редактором или вьювером
__________________
Axapta v.3.0 sp5 kr2 |
|
27.07.2011, 08:23 | #9 |
MCITP
|
Я думаю, что, всё таки, это html с расширением xls.
Поэтому, если посмотреть вторую строку подключения,которая получает доступ к файлу, есть строка X++: Extended Properties='HTML Import Надеюсь на подсказку. |
|
27.07.2011, 09:33 | #10 |
Участник
|
А если его переименовать обратно в report.html и попробовать загрузить через ADO?
__________________
Axapta v.3.0 sp5 kr2 |
|
27.07.2011, 09:39 | #11 |
MCITP
|
Ничего не меняется, что ,думаю, логично. Т.к. до расширения ADO всё равно, как я думаю. Что прописано в строке подключения, так он и будет подключаться к файлу.
|
|
27.07.2011, 09:41 | #12 |
Moderator
|
А если и с другой стороны попробовать - открыть его в Excel и сохранить как настоящий файл Excel при помощи Save As? Этот новый файл будет обрабатываться классом импорта?
P.S. Естественно с ExtendedProperties = Excel... |
|
27.07.2011, 09:58 | #13 |
MCITP
|
Да, это всё сработает отлично. Т.е. открыть файл, пересохранить его в нормальном формате Excel.
Но задача состоит в том, чтобы не производить данных манипуляций, а обработать файл таким какой он есть. Т.е. файл будет приходить постоянно, а формат его никто менять не будет. Грубо говоря, необходимо следущее - обработать файл таким какой он есть непосредственно средствами аксапты, чтобы пользователь нажал кнопку, например, "Импорт" и всё. Возможно, я использую не те инструменты для данной обработки. Поэтому жду советов как это сделать правильнее. |
|
27.07.2011, 10:09 | #14 |
Участник
|
Попробуйте добавить в хидер такой тег
X++: <head> ... <title>Report</title> ... </head>
__________________
Axapta v.3.0 sp5 kr2 |
|
27.07.2011, 10:31 | #15 |
Moderator
|
Ну, ёлка-палка... Дык, его формат менять не надо. Откройте в Excel, "сохраните как" в Excel, прочитайте новый файл классом gl00mie и удалите новый файл. Всё - конечно, программно, не вручную. И всё незаметно для пользователя.
|
|
27.07.2011, 11:26 | #16 |
MCITP
|
Цитата:
Откройте в Excel, "сохраните как" в Excel....Всё - конечно, программно, не вручную
Также не понятно одно - если мы откроем его для сохранения, то зачем нам его сохранять. Лучше взять и обработать. Только не понятно как. |
|
27.07.2011, 11:27 | #17 |
MCITP
|
|
|
27.07.2011, 11:46 | #18 |
Участник
|
Кстати, а картинка - содержимое вашего файла?
Тег META там почему-то не закрыт По идее, head должен выгядеть так X++: <head> <META http-equiv="Content-type" content="text/html; charset=ISO8859-1" /><title>Report</title></head>
__________________
Axapta v.3.0 sp5 kr2 Последний раз редактировалось AndyD; 27.07.2011 в 11:50. |
|
27.07.2011, 12:42 | #19 |
Moderator
|
Запишите макрос в Excel, т.е. в пустом Экселе включите запись макро, далее откройте свой файл, сохраните его как xls, закройте файл, выключите запись макро. Получившийся код VBA несите сюда - я помогу его оформить на X++.
Импорт при помощи ADO работает с СОХРАНЕННЫМ файлом на диске! (этот файл как бы БД для него). К тому же, для несохраненного файла вы не сможете указать параметры строки подключения. Поэтому сохранение обязательно при использовании класса gl00mie. |
|
27.07.2011, 12:47 | #20 |
MCITP
|
Картинка - содержимое файла.
Спасибо за советы, но это не помогает. |
|