V
VitAl2013
Гость
Версия AutoIt: 3.
3.3.6.0
Описание:
Требуется создать функцию на выходе у которой будет массив.
Функция должна парсить файл, находить внутри него куски, анализировать их, заменять некоторые значения на другие. И выдавать информацию, но это обстрактно и в общих чертах.
Что она делает "по человечески": есть файл чертежа (drw), в котором присутсвуте информация о кол-ве листов в нём, о том какой размер у этих листов, и в каких единицах он записан.
Что она делает "по программе":
1. Вычленяет блоки. Делиметр "18 18 18 E1". Сохраняет их в массив.
2. В 1 элементе массива мы можем узнать только единицы измерения форматки 1 листа чертежа. Узнаем, запоминаем и удаляем этот элемент.
3. Во 2 элементе читаем что следует за x_size - это ширина форматки 1 листа, таким же образом узнаем высоту форматки (специальной рамки на чертеже) и её имя. Также из 2 элемента массива узнаем единицы измерения следующей форматки (мм или дюймы)
4. В 3 и последущих элементах нет признаков параметров x_size или y_size, но мы знаем что там идут сразу значения, просто читаем их.
Теперь как мы их читаем. Значения высоты и ширины - вещественные числа. Прошка (Это та программа которая делает чертёж) хранит их в упакованном виде. Т.е. если значение целое (в мм), то прое отдает на него 3 байта, если дробное (в INCH) - то 8 байт. Строки заканчиваются "00".
Допустим мы прочли значение высоты 2F 7A 40. Для того чтобы узнать что это за число и предназначена функция GetDoubleValue (это в коде Дельфи, смотреть в примечаниях). Она расшифровывает это проешное hex-значение до реального 420. Правила как она это делает лучше смотреть в коде Дельфи. Дело в том что записанное double значение числа 420 это "40 7A 40", но Прошка заменяет первое число на 2F или другое число. Всё это уже вычислено и выведено в функци GetDoubleValue.
Примечания:
Темы связанные с этой проблемой.
http://fsapr2000.ru/index.php?showtopic=34742 - тут я зашёл с другого конца, так сказать, и получил ответ в виде кода на Дельфи. Смотреть аттач. http://www.wikifortio.com/772603/Get_DrwSheet.7z
Также создал тему http://autoit-script.ru/index.php?topic=1441.0 - понял что пока для меня работа с double в новинку.
Вот уже мои наработки (осталось функцию GetDoubleValue переварить):
Вот собственно и функция:
Соединить их пока не получается, так как выкидывает, отписал тут: http://autoit-script.ru/index.php?topic=1480.0
Вот что получилось на 5 апреля 2010, требуется оптимизация и шлифовка:
3.3.6.0
Описание:
Требуется создать функцию на выходе у которой будет массив.
Функция должна парсить файл, находить внутри него куски, анализировать их, заменять некоторые значения на другие. И выдавать информацию, но это обстрактно и в общих чертах.
Что она делает "по человечески": есть файл чертежа (drw), в котором присутсвуте информация о кол-ве листов в нём, о том какой размер у этих листов, и в каких единицах он записан.
Что она делает "по программе":
1. Вычленяет блоки. Делиметр "18 18 18 E1". Сохраняет их в массив.
2. В 1 элементе массива мы можем узнать только единицы измерения форматки 1 листа чертежа. Узнаем, запоминаем и удаляем этот элемент.
3. Во 2 элементе читаем что следует за x_size - это ширина форматки 1 листа, таким же образом узнаем высоту форматки (специальной рамки на чертеже) и её имя. Также из 2 элемента массива узнаем единицы измерения следующей форматки (мм или дюймы)
4. В 3 и последущих элементах нет признаков параметров x_size или y_size, но мы знаем что там идут сразу значения, просто читаем их.
Теперь как мы их читаем. Значения высоты и ширины - вещественные числа. Прошка (Это та программа которая делает чертёж) хранит их в упакованном виде. Т.е. если значение целое (в мм), то прое отдает на него 3 байта, если дробное (в INCH) - то 8 байт. Строки заканчиваются "00".
Допустим мы прочли значение высоты 2F 7A 40. Для того чтобы узнать что это за число и предназначена функция GetDoubleValue (это в коде Дельфи, смотреть в примечаниях). Она расшифровывает это проешное hex-значение до реального 420. Правила как она это делает лучше смотреть в коде Дельфи. Дело в том что записанное double значение числа 420 это "40 7A 40", но Прошка заменяет первое число на 2F или другое число. Всё это уже вычислено и выведено в функци GetDoubleValue.
Примечания:
Темы связанные с этой проблемой.
http://fsapr2000.ru/index.php?showtopic=34742 - тут я зашёл с другого конца, так сказать, и получил ответ в виде кода на Дельфи. Смотреть аттач. http://www.wikifortio.com/772603/Get_DrwSheet.7z
Также создал тему http://autoit-script.ru/index.php?topic=1441.0 - понял что пока для меня работа с double в новинку.
Вот что получилось на 5 апреля 2010, требуется оптимизация и шлифовка:
Код:
#include <GUIListView.au3>
Dim $result[2][3]
do
$var = FileOpenDialog("Дай drw файл! Или жми Cancel для выхода.", "c:\", "Pro/E drawing (*.drw.*)", 1) ;*.drw.* - именно так - особенности Pro/Engineer
if @error then
Exit
EndIf
drawinfo($var)
_ArrayDisplay($result, $var)
until GUIGetMsg() = -3
func drawinfo($way_to_file)
$chFileHnd = FileOpen($way_to_file, 4)
Do
$chFileTxt = FileRead($way_to_file)
until @error = 0
if StringInStr(StringToBinary($chFileTxt), "6E616D65004D4D00E001756E69745F7479") > 0 then
;~ ConsoleWrite ("6E616D65004D4D00E001756E69745F7479 - yes"&@CRLF)
$result[0][0]="mm"
else
;~ ConsoleWrite ("6E616D65004D4D00E001756E69745F7479 - no"&@CRLF)
EndIf
if StringInStr(StringToBinary($chFileTxt), "6E616D6500494E434800E001756E69745F74797065") > 0 then
;~ ConsoleWrite ("6E616D6500494E434800E001756E69745F74797065 - yes"&@CRLF)
$result[0][0]="inch"
else
;~ ConsoleWrite ("6E616D6500494E434800E001756E69745F74797065 - no"&@CRLF)
endif
$p_format = StringInStr(StringToBinary($chFileTxt), "00705F666F726D617400", 0, 1)
$next_table = StringInStr(StringToBinary($chFileTxt), "006E6578745F7461626C6500", 0, 1)
$pf_nt = StringMid(StringToBinary($chFileTxt), $p_format, $next_table-$p_format)
$result_2 = StringSplit ( $pf_nt, "181818E1" , 1 )
;~ _ArrayDisplay($result_2, "fresh")
_ArrayDelete ( $result_2, 0)
Redim $result[UBound($result_2)][3]
;~ _ArrayDisplay($result, "$result-1")
;~ _ArrayDelete ( $result_2, 0)
;~ _ArrayDisplay($result_2, "fresh-2")
for $i = 0 to UBound($result_2)-1 step 1
;~ ConsoleWrite ("$i = "&$i&@CRLF)
if StringInStr($result_2[$i], "4D4D00") > 0 then
;~ ConsoleWrite ("4D4D00 mm - yes"&@CRLF)
$result[$i+1][0]="mm"
$e1_plus = 6
else
;~ ConsoleWrite ("4D4D00 mm - no"&@CRLF)
EndIf
if StringInStr($result_2[$i], "494E434800") > 0 then
;~ ConsoleWrite ("494E434800 inch - yes"&@CRLF)
$result[$i+1][0]="inch"
$e1_plus = 6;8
else
;~ ConsoleWrite ("494E434800 inch - no"&@CRLF)
endif
$e1 = StringInStr($result_2[$i], "00E3")
;~ ConsoleWrite ($e1 & " - " &VarGetType($e1) &@CRLF)
$x1 = StringInStr($result_2[$i], "785F73697A6500") ;есть ли x_size и какая позиция у буквы x
;~ ConsoleWrite ($x1&@CRLF)
if $x1>0 Then ;если она есть то
$cx = StringSplit(StringTrimLeft($result_2[$i], $x1+13), "E0", 1); удалив $a1+13 число символов слева элемента $result_2[0] разобъём его на элементы по делиметру E0
;~ _ArrayDisplay($c, "c")
$result [$i][1] = _normalize_double(StringRight($cx[1], $e1_plus))
;~ $result [1][0] = $b1
;~ ConsoleWrite($result [$i][0] & @CR)
else
$result [$i][1] = _normalize_double(StringMid( $result_2[$i], $e1+6, $e1_plus))
EndIf
$y1 = StringInStr($result_2[$i], "795F73697A6500") ;есть ли y_size и какая позиция у буквы y
if $y1>0 Then ;если она есть то
$cy = StringSplit(StringTrimLeft($result_2[$i], $y1+13) , "E0", 1); удалив $a1+13 число символов слева элемента $result_2[0] разобъём его на элементы по делиметру E0
;~ _ArrayDisplay($c, "c")
$result [$i][2] = _normalize_double(StringRight($cy[1], $e1_plus))
;~ $result [1][0] = $b1
;~ ConsoleWrite($result [$i][0] & @CR)
Else
$result [$i][2] = _normalize_double(StringMid( $result_2[$i], $e1+12, $e1_plus))
EndIf
next
$result[0][1] = UBound($result_2)-1
$result[0][2] = "lists"
;~ _ArrayDisplay($result_2, "result_2")
;~ check-begin
$chFileTxt2= StringReplace($chFileTxt, "PicturePrimdata#", "")
$NumberOfLists = @extended/2
if $result[0][1]<>$NumberOfLists Then
MsgBox (64, "Error $result[0][0]<>$NumberOfLists", "Possible error in list number ")
EndIf
;~ check-end
;~ MsgBox (64, "$p_format", $pf_nt)
;~ " next_table "="006E6578745F7461626C6500"
;~ " p_format " = "00705F666F726D617400"
;~ "x_size " = "785F73697A6500"
;~ "y_size " = "795F73697A6500"
EndFunc
Func _normalize_double($hex)
Local $result
$f_00 = False
$fhex = ""
$plus = stringleft ($hex, 2)
$cplus = ''
if $plus <= "23" then
$cplus = "3E"
ElseIf $plus >= "28" and $plus <= "2C" then
$cplus = "3F"
ElseIf $plus >= "2D" and $plus <= "3F" then
$cplus = "40"
if $plus = "2F" then
$f_00 = True
EndIf
ElseIf $plus >= "4A" and $plus <= "4C" then
$cplus = BinaryToString(Hex(Dec($cplus)+101, 2))&"3F"
ElseIf $plus = "4D" then
$cplus = BinaryToString(Hex(Dec($cplus)+104, 2))&"3F"
ElseIf $plus >= "4E" and $plus <= "53" then
$cplus = BinaryToString(Hex(Dec($cplus)+114, 2))&"3F"
ElseIf $plus >= "54" and $plus <= "57" then
$cplus = BinaryToString(Hex(Dec($cplus)+115, 2))&"3F"
ElseIf $plus >= "58" and $plus <= "59" then
$cplus = BinaryToString(Hex(Dec($cplus)+116, 2))&"3F"
ElseIf $plus >= "5A" and $plus <= "8A" then
$cplus = BinaryToString(Hex(Dec($cplus)+117, 2))&"3F"
ElseIf $plus >= "8B" and $plus <= "9F" then
$cplus = BinaryToString(Hex(Dec($cplus)-139, 2))&"40"
ElseIf $plus = "A0" then
$cplus = "1540"
ElseIf $plus = "A1" then
$cplus = "1640"
ElseIf $plus = "A2" then
$cplus = "1740"
ElseIf $plus >= "A3" and $plus <= "AF" then
$cplus = "1840"
EndIf
;~ ConsoleWrite("1) "&$cplus&@CRLF)
if StringLen($hex)>14 then
;~ ConsoleWrite("2) "&$hex&@CRLF)
$hex = StringRight($hex, 14)
;~ ConsoleWrite("3) "&$hex&@CRLF)
EndIf
For $i = StringLen($hex) - 1 To 3 Step -2
$fhex &= StringMid($hex, $i, 2)
Next
;~ ConsoleWrite("4) "&$fhex&@CRLF)
$fhex &= $cplus
;~ ConsoleWrite("5) "&$fhex&@CRLF)
if StringLen($fhex)<=16 then
if $f_00 then
for $a = 16-StringLen($fhex) to 2 step -2
$fhex = Stringleft($fhex, 2)&$fhex
;~ ConsoleWrite("5.1) "&$fhex &" Length:"&stringlen($fhex)& @CR); проверить тут
next
else
for $a = 16-StringLen($fhex) to 1 step -1
$fhex = "0"&$fhex
next
EndIf
$fhex = "0x"&$fhex
else
;~ ConsoleWrite("It's bigger than 16 digits" & @CR)
$fhex = ""
endif
;~ ConsoleWrite("6) "&$fhex&@CRLF)
$result = _Decode($fhex)
;~ ConsoleWrite("7) "&$result&@CRLF)
if $hex = "07" then
$result = 0.001
ElseIf $hex = "09" then
$result = 0.005
ElseIf $hex = "0A" then
$result = 0.01
ElseIf $hex = "0D" then
$result = 0.25
ElseIf $hex = "0E" then
$result = 0.5
ElseIf $hex = "0F" then
$result = 1
ElseIf $hex = "18" then
$result = "0"
ElseIf $hex = "000C9A" then
$result = "0,1"
EndIf
return $result
EndFunc
Func _Decode($bValue)
$bValue = Binary($bValue)
Local $tStruct1, $tStruct2
;~ ConsoleWrite("8) "&$bValue&@CRLF)
$tStruct1 = DllStructCreate('uint64')
;~ ConsoleWrite("9) "&$tStruct1&@CRLF)
DllStructSetData($tStruct1, 1, $bValue)
$tStruct2 = DllStructCreate('double', DllStructGetPtr($tStruct1))
;~ ConsoleWrite("10) "&$tStruct2&@CRLF)
Return DllStructGetData($tStruct2, 1)
EndFunc