Русское сообщество AutoIt

  • Май 22, 2013, 14:59:11 *
  • Добро пожаловать, Гость
Пожалуйста, войдите или зарегистрируйтесь.

Войти
Расширенный поиск  

Новости:

Создан файловый архив для участников форума.

Закачивайте свои файлы и получайте рейтинг, прямые ссылки, и т.п.

Для изображений и скриншотов по прежнему есть AUTOIT.RV.UA

Реклама

Автор Тема: Функция вычленения информации из файла с применением double переменных.  (Прочитано 1117 раз)

0 Пользователей и 1 Гость смотрят эту тему.

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
Также создал тему Как работать с double типами данных? - понял что пока для меня работа с double в новинку.

Вот уже мои наработки (осталось функцию GetDoubleValue переварить):

Вот собственно и функция:

Соединить их пока не получается, так как выкидывает, отписал тут: Крах скрипта связанный с присвоением данных массиву через функцию

Вот что получилось на 5 апреля 2010, требуется оптимизация и шлифовка:
Код: AutoIt [Выделить]
#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


Внимание: Для просмотра прикреплённых файлов необходимо Войти или Зарегистрироваться
« Последнее редактирование: Апрель 05, 2010, 07:59:14 от VitAl2013 »



  Записан
 


Похожие темы
Тема Автор Ответов Просмотров Последний ответ
Как работать с double типами данных?
AutoIt для новичков
VitAl2013 8 1442 Последний ответ Апрель 01, 2010, 11:01:36
от VitAl2013
Перемещение файлов с применением политик доступа
AutoIt для новичков
SANILA 8 2153 Последний ответ Февраль 16, 2011, 15:26:15
от SANILA
Некоректно отрабатывает функция создания ListView из файла-источника
AutoIt для новичков
saavaage 2 1572 Последний ответ Октябрь 07, 2010, 01:03:46
от saavaage
Регулярное выражение для вычленения начального фрагмента строки
Регулярные выражения и прочее
Rjevsky 2 1016 Последний ответ Ноябрь 17, 2010, 17:35:32
от Kaster
Регулярное выражение для вычленения среднего фрагмента строки (IP)
Регулярные выражения и прочее
Rjevsky 2 1107 Последний ответ Ноябрь 18, 2010, 09:38:56
от gregaz
Извлечение информации из файла с промежутками
Регулярные выражения и прочее
_Lexa98_ 18 1457 Последний ответ Февраль 14, 2012, 20:36:59
от _Lexa98_
Перенесено: Извлечение информации из файла
AutoIt для новичков
madmasles 0 320 Последний ответ Февраль 12, 2012, 20:58:30
от madmasles
Удаление информации об источнике получения файла
Полезняшки
Yashied 14 1623 Последний ответ Май 31, 2012, 19:33:31
от beliy
Перенесено: Прошу привести пример создания файла, сбора информации из памяти.....
Стол заказов
madmasles 0 496 Последний ответ Июль 21, 2012, 10:06:28
от madmasles
Получение из имени файла текста с последующим применением
AutoIt для новичков
foster23 4 415 Последний ответ Октябрь 21, 2012, 00:41:27
от foster23


Реклама

* Последние сообщения на форуме
post Иконки в диалоге и скорость запуска скрипта
[AutoIt для новичков] gora Сегодня в 14:18:06
post Re: Какая музыка вам нравится?
[Общение] Mur Сегодня в 14:07:38
post Re: Сохранение введённых данных.
[GUI - Графический интерфейс пользователя] madmasles Сегодня в 14:01:09
post Re: Сохранение введённых данных.
[GUI - Графический интерфейс пользователя] vijei Сегодня в 13:38:09
post Re: [Элементы GUI] Дочернее окно с рамкой на фоне родительского, в Windows XP
[GUI - Графический интерфейс пользователя] InnI Сегодня в 13:06:43
post Re: Сохранение введённых данных.
[GUI - Графический интерфейс пользователя] InnI Сегодня в 12:53:12
post [Элементы GUI] Дочернее окно с рамкой на фоне родительского, в Windows XP
[GUI - Графический интерфейс пользователя] WSWR Сегодня в 12:32:14
post Перенесено: Какой стиль позволяет в элементе GUICtrlCreateEdit создавать другие GUI обьекты?
[AutoIt для новичков] madmasles Сегодня в 09:35:34
post Перенесено: [Элементы GUI] Использование Image листа в кнопках
[AutoIt для новичков] madmasles Сегодня в 09:35:13
post Перенесено: Сохранение введённых данных.
[AutoIt для новичков] madmasles Сегодня в 09:34:45

* Пользователи онлайн
  • Dot Гостей: 151
  • Dot Скрыт: 1
  • Dot Пользователей: 29
  • Dot Пользователи Online: