Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   Как определить кодировку строки передаваемой как значение параметра OLE-серверу Excel (http://forum.oszone.net/showthread.php?t=193637)

RUVATA 11-12-2010 12:28 1563200

Как определить кодировку строки передаваемой как значение параметра OLE-серверу Excel
 
Всем доброго времени суток...
Я занимаюсь переводом некоторых разделов справки (UDFs3.chm), а именно касающихся Excel.au3 и Word.au3
В процессе перевода обнаружил множество ошибок, как в тексте справки, примерах, так и багов в самом Excel.au3
И вот собственно занимаюсь их решением ... (некоторые решены своими силами, но для некоторых - знаний в AutoIT мне явно не хватает, нужна помощь коллективного разума :) ) (Я опытный VBA-программист, но как AutoIT-эр я новичок)

функция _ExcelNumberFormat в составе Excel.au3 - просто не работает в большинстве случаев

"разбор полетов" показал, что OLE-сервер Excel получает одним из аргументов к объекту
Excel.Application.ActiveSheet.Range(такая-то, такая-то).NumberFormat некорректные строки
(для этого аргумента существуют специальные строковые обозначения форматов для ячеек н/п "#,##0.00$" обозначает "currency" (Валюта), в данном случае валюта(по умолчанию) с двумя разрядами)

вот этот код вызовет ошибку в значении $sFormat
Код:

; ***************************************************************
; Пример 1 - Изменение формата данных в целевом диапазоне ячеек
; *****************************************************************
#include <Excel.au3>

Local $oExcel = _ExcelBookNew() ;Создаем новую рабочую книгу и отображает ее

; Циклически заполняем диапазон ячеек случайнвми числами
For $y = 1 To 10
        For $x = 1 To 10
                _ExcelWriteCell($oExcel, Random(1000, 10000), $x, $y) ;Записываем в ячейку случайное целое число из диапазона от 1000 до 100000
        Next
Next

$sFormat = "#,##0.00$" ; "#,##0.00$" - условное строковое обазначение формата "currency" (Валюта)

With $oExcel.ActiveSheet
.Range(.Cells(1,1),.Cells(5,5)).NumberFormat = $sFormat
EndWith

MsgBox(0, "_ExcelNumberFormat | Пример 1", "Демонстрация завершена, нажмите ОК")
_ExcelBookSaveAs($oExcel, @TempDir & "\Temp.xls", "xls", 0, 1) ; Сохраняем файл в директории временных файлов, перезаписывая если необходимо.
_ExcelBookClose($oExcel) ; Закрываем рабочую книгу

а вот этот - нет (
Код:

; ***************************************************************
; Пример 1 - Изменение формата данных в целевом диапазоне ячеек
; *****************************************************************
#include <Excel.au3>

Local $oExcel = _ExcelBookNew() ;Создаем новую рабочую книгу и отображает ее

; Циклически заполняем диапазон ячеек случайнвми числами
For $y = 1 To 10
        For $x = 1 To 10
                _ExcelWriteCell($oExcel, Random(1000, 10000), $x, $y) ;Записываем в ячейку случайное целое число из диапазона от 1000 до 100000
        Next
Next

$sFormat = "[$-F800]dddd, mmmm dd, yyyy" ; "[$-F800]dddd, mmmm dd, yyyy" - условное строковое обазначение формата "long date" (длинная лата)

With $oExcel.ActiveSheet
.Range(.Cells(1,1),.Cells(5,5)).NumberFormat = $sFormat
EndWith

MsgBox(0, "_ExcelNumberFormat | Пример 1", "Демонстрация завершена, нажмите ОК")
_ExcelBookSaveAs($oExcel, @TempDir & "\Temp.xls", "xls", 0, 1) ; Сохраняем файл в директории временных файлов, перезаписывая если необходимо.
_ExcelBookClose($oExcel) ; Закрываем рабочую книгу

Несколько экспериментов привели меня к выводу, что не правильно обрабатываются лишь те обозначения в которых содержатся символы "#" , "?".

Мне кажется это может быть вопрос кодировки, вот я и хотел-бы спросить
1) во первых - как узнать в какой кодировке AutoIT передает строку OLE-серверу Excel?
2) во вторых - каким способом можно кодировку строк менять?
3) ну и в третьих - Ваши соображения и предложения, я могу ошибаться, что-то может еще быть связанное с OLE/COM (сложная тема)

madmasles 11-12-2010 13:00 1563209

RUVATA,
Я проверял только в Excel 2003 (рус). Вот, например, такой формат $sFormat = '# ##0,00[$$-409]_ ;[Красный]-# ##0,00[$$-409]\ ' у меня работает. Наверное, у англ. версии формат будет другой, может быть в 2007-ом и 2010-ом тоже.
И такой $sFormat = '_-* # ##0,00р._-;-* # ##0,00р._-;_-* "-"??р._-;_-@_-' тоже работает.
Длинная дата у меня так $sFormat = 'ДД.ММ.ГГГГ'.

RUVATA 11-12-2010 13:25 1563219

madmasles, Может и так...
но смущает вот что...
Excel 2007 Rus
в столбик циферки к каждой ручками применяем какой ни будь формат
потом читаем его в VBA (так де-факто проще получать строковые обозначения форматов, по таблице MSDN задрючишся :))
Проведи ка у себя такой эксперимент...
Открой новую книгу Excel в столбец "A" вертикльно запиши какие ни будь числа (штук 7), потом "руками" поменяй форматы ячеек
Alt+F11 откроется редaктор VBA - меню "Insert" > "Module"
вставь и выполни вот этот код
Код:


Sub FormatString()
Dim MyRange As Range
Set MyRange = Range("A1")

Do While MyRange.Value <> ""
    MyRange.Offset(0, 1).Value = MyRange.NumberFormat
    Set MyRange = MyRange.Offset(1, 0)
Loop

End Sub

в соседнем столбце запишутся строковые обозначения соответствующих форматов
выложи пожалуйста несколько, надо сравнить.

PS: У меня формат currency VBA определяет как "#,##0.00$" и при этом AutoIT его не передает именно так, - не работает а "[$-F800]dddd, mmmm dd, yyyy" работает - почему...
Протестировал уже на 3-х машинах на 3-х версиях Office: 2007(Eng), 2007(Rus), 2010(Rus).

kaster 11-12-2010 13:38 1563223

RUVATA, "ошибочный" код у меня отработал нормально
MS OFfice 2010 Rus x64
MS Win7 Rus x64

madmasles 11-12-2010 13:40 1563224

Код:

123,3                        General
23 434,20                #,##0.00
$567,34                _-[$$-409]* #,##0.00_ ;_-[$$-409]* -#,##0.00 ;_-[$$-409]* "-"??_ ;_-@_
34,00р.                _($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)
25.02.1900                m/d/yyyy
18 марта 1900 г.        [$-F800]dddd, mmmm dd, yyyy
30.03.00                dd/mm/yy;@
12330,00%                0,00%
4:48:00                        [$-F400]h:mm:ss AM/PM
567 1/3                        # ?/?
-34,00р.                $#,##0.00_);[Red]($#,##0.00)

RUVATA,
Макрос у меня показал формат '$#,##0.00_);[Red]($#,##0.00)', но с ним вываливается ошибка. Посмотрел вручную, там такой '[$$-409]# ##0,00_ ;[Red]-[$$-409]# ##0,00\ '? с ним работает.

RUVATA 11-12-2010 13:52 1563234

Цитата:

Цитата kaster
"ошибочный" код у меня отработал нормально »

так это уже что-то...
Теперь осталось найти загвостку...
кто шарит в OLE/COM ?

madmasles, попробуйте пожалуйста в _ExcelNumberFormat
#,##0.00
0,00%
# ?/?
$#,##0.00_);[Red]($#,##0.00)
Все ли работают?

madmasles 11-12-2010 14:08 1563247

RUVATA,
Код:

'#,##0.00' не работает, так '# ##0,00' работает.
0,00% работает.
'# ?/?' не работает, так '#" "?/?' работает.
'$#,##0.00_);[Red]($#,##0.00)' не работает, так '0,00_ ;[Красный]-0,00\ ' работает.


RUVATA 11-12-2010 14:12 1563248

Хотя "гора с плеч" стало быть проблема индивидуально у меня, и перевод собственно продолжается :)
Хотя разобраться стоит дабы описать возможные проблемы.

Давайте обсудим - с чем это может быть связанно
Еще раз опишу положение вещей:
AutoIT взаимодействует с Excel по средствам обращения к OLE-серверу запущенного экземпляра программы, именно OLE а не COM, обращение к COM-серверу (особая специфика легко запутаться)
Скрипт передает в метод некоему объекту параметр (тип "String" на cтороне Excel) вот здесь кстати у AutoIT проблема ИМХО (нет разделения типов).
Пробуем передать
"#,##0.00$" однозначно верная для метода строка - нарываемся на ошибку а именно:
Код:

D:\Test\test.au3 (20) : ==> The requested action with this object has failed.:
.Range(такая-то).NumberFormat = $sFormat
.Range(такая-то).NumberFormat = $sFormat^ ERROR

Предаем "[$-F800]dddd, mmmm dd, yyyy" однозначно верная для метода строка - Ошибки не происходит.
Вывод
Объект получает "[$-F800]dddd, mmmm dd, yyyy" - как есть, а "#,##0.00$" не так как есть

PS: Только что проверил аналогичную схему из C# (Visual Studio 2010).
и "#,##0.00$" прошел замечательно.

madmasles, Отлично...
и так проблема все таки есть... но не видно системы...
Пока остается лишь тестить пока не выявится закономерность.

kaster 11-12-2010 14:28 1563260

Цитата:

Цитата RUVATA
проблема индивидуально у меня »

это всегда должно быть ключевым моментом при выдвижении заявлений, по типу
Цитата:

Цитата RUVATA
обнаружил множество ошибок, как в тексте справки, примерах, так и багов в самом Excel.au3 »

я к тому, что сообщество и создатели языка довольно тщательно следят за тем, что идет в стандартную поставку, и вероятность ошибок хоть и есть, но, уверен, сведена к минимуму.

RUVATA 12-12-2010 15:16 1564040

Цитата:

Цитата kaster
проблема индивидуально у меня » »

Между прочим - оказалось не индивидуально у меня... см. о чем пишет madmasles.
И именно эта проблема лишь одна из нескольких, когда я закончу работу -
милости прошу ознакомиться... критика приветствуется :) э-т полезно

Цитата:

Цитата kaster
что сообщество и создатели языка довольно тщательно следят за тем »

Я ни коим случаем не умоляю труда проделанного сообществом, просто с момента составления именно этой UDF "много воды утекло" и основным фактором является появление принципиально отличающейся платформы Office 2007-2010, лвиная доля связанна именно с этим, но и в 2003 видимо кое что изменилось, так что я скорее не исправляю ошибки а делаю поправку на текущее положение вещей.

kaster 12-12-2010 23:56 1564456

RUVATA, ошибки madmasles, вроде как из-за языка офиса. а вообще да, та библиотека делалась под 2003.

RUVATA 13-12-2010 15:17 1564849

kaster,
Цитата:

Цитата kaster
вроде как из-за языка офиса »

вот здесь позволь не согласиться...
язык который используется для автоматизации пантеона приложений MS Office назывется VBA (Visual Basic for Applications),
фактический являтся языком Visual Basic, ныне эволюционировавший в vb.NET
Основная объектная модель приложений Office не изменяется аш с версии 97-го года.
Учитывая что язык широко используется на протяжении уже 13-лет - вероятность что в нем есть ошибки такого рода как "не верно работающий метод" - крайне мала, хотя исключать ее все таки нельзя.
Но вот что показывает моя практика(с VBA работаю уже около 7 лет), и несколько поставленных экспериментов:
1) Управление программи MS Office из вне, т.е. другими языками, осуществляется как правило через OLE-сервер (COM-сервер используется реже имеет свои особенности реализации, и применяется чаще всего тогда, когда необходимо использовать компоненты Office не запуская само приложение, например широко применялась практика использования модулей MS Word "проверка орфографии" для проверки содержимого тестовых полей программ написанных на том-же C# или vb.NET, даже видел реализацию на Java (хотя там на этот счет есть более лаконичные решения).
Взаимодействие с OLE-сервером, происходит по принципу обращения к объектной модели конкретного приложения, обработка обращений в таком случае происходит по правилам VBA но не через него, вы получаете возможность опускать прараметры методов и т.д.
Скомпилированные программы написанные на языках: С++ и C#, vb.NET, Java и даже встроенный язык 1C не имеют с этим проблем а AutoIT имеет - вывод напрашивается сам сабой.
2) Природа этой ошибки до сих пор не ясна - не понятно гна каком этапе она возникает: AutoIT передает значение, OLE-сервер обрабатывает и передает в COM, COM-объект принемает, или уже само Приложение реализует инструкции COM.
Тут необходимо обладать огромной базой знаний о технологии COM и устройстве Office Excel (у меня таких знаний нет, по крайней мере про COM)

kaster 13-12-2010 23:22 1565195

RUVATA, я имел в виду язык локализации - русский


Время: 09:31.

Время: 09:31.
© OSzone.net 2001-