Что нового

Не срабатывает дополнительная проверка Select...Case...EndSelect (многократное повторение результата)

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Доброго времени суток. Продолжаю мучать смарт винтов. Составляю массив из "официальных" значений (id). Но уже пару раз сталкивался, что мой список этих значений не полный. Если привязывать вывод результатов к своему списку значений, то естественно выводится не весь список. Захотел добавить проверку и там где отсутствует "официальное" значение, хотел заменять на допустим "Спецификация производителя" или что-то подобное. Добавил ещё одну проверку конструкцией Select...Case...EndSelect. Оно то срабатывает, но выводит кучу повторов.
Делаю так:
Код:
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUITab.au3>
#include <GUIListView.au3>
#include <GUIImageList.au3>
#include <String.au3>
#include <Array.au3>

Global    $sSMARTCodeTxt =  "10*0A*Spin-Up Retry Count*Число повторных попыток раскрутки дисков до рабочей скорости в случае если первая попытка была неудачной.;" & _
                        "11*0B*Recalibration Retries*Количество повторов запросов рекалибровки в случае если первая попытка была неудачной.;" & _
                        "12*0C*Device Power Cycle Count*Количество полных циклов включения-выключения диска.;" & _
                        "13*0D*Soft Read Error Rate*Число ошибок при чтении по вине программного обеспечения, которые не поддались исправлению.;" & _
                        "100*64*Erase/Program Cycles (для SSD)*Общее количество циклов стирания / программирования для всей флэш-памяти за все время ее существования.;" & _
                        "103*67*Translation Table Rebuild (для SSD)*Количество событий когда внутренние таблицы адресов блоков были повреждены и впоследствии восстановлены.;" & _
                        "170*AA*Reserved Block Count (для SSD)*Состояние пула резервных блоков.;" & _
                        "171*AB*Program Fail Count (для SSD)*Число попыток когда запись во флэш-память не удалась.;" & _
                        "172*AC*Erase Fail Count (для SSD)*Количество сбоев операции стирания на флэш-памяти.;" & _
                        "173*AD*Wear Leveller Worst Case Erase Count (для SSD)*Максимальное количество операций стирания выполняемых для одного блока флэш-памяти.;" & _
                        "174*AE*Unexpected Power Loss (для SSD)*Число неожиданных отключений питания когда питание было потеряно до получения команды на отключение диска.;" & _
                        "175*AF*Program Fail Count (для SSD)*Число попыток когда запись во флэш-память не удалась.;" & _
                        "176*B0*Erase Fail Count (для SSD)*Количество сбоев операции стирания на флэш-памяти.;" & _
                        "177*B1*Wear Leveling Count (для SSD)*Максимальное количество операций стирания, выполняемых для одного блока флэш-памяти.;" & _
                        "178*B2*Used Reserved Block Count (для SSD)*Состояние пула резервных блоков.;" & _
                        "179*B3*Used Reserved Block Count (для SSD)*Состояние пула резервных блоков.;" & _
                        "180*B4*Unused Reserved Block Count (для SSD)*Состояние пула резервных блоков.;" & _
                        "181*B5*Program Fail Count (для SSD)*Число попыток, когда запись во флэш-память не удалась.;" & _
                        "182*B6*Erase Fail Count (для SSD)*Количество сбоев операции стирания на флэш-памяти.;" & _
                        "183*B7*SATA Downshifts (для SSD)*Указывает, как часто требовалось снизить скорость передачи данных SATA ;" & _
                        "184*B8*End-to-End error*Число ошибок обмена через кэш. Данный атрибут — часть технологии HP SMART IV — означает, что после передачи данных через кэш-память чётность данных между хостом и жёстким диском не совпадает.;" & _
                        "187*BB*Reported UNC Errors*Ошибки, которые не могли быть восстановлены, используя методы устранения ошибки аппаратными средствами.;" & _
                        "188*BC*Command Timeout*Количество прерванных операций в связи с HDD тайм-аут.;" & _
                        "189*BD*High Fly Writes*Cодержит количество зафиксированных случаев записи при высоте полета головки выше рассчитанной;" & _
                        "190*BE*Airflow Temperature (WDC)*Температура воздуха внутри корпуса жёсткого диска.;" & _
                        "191*BF*G-sense error rate (Mechanical Shock)*Количество ошибок, возникающих в результате ударных нагрузок.;" & _
                        "192*C0*Power-off retract count*Число циклов выключений или аварийных отказов (включений/выключений питания накопителя).;" & _
                        "193*C1*Load/Unload Cycle*Количество циклов перемещения блока магнитных головок в парковочную зону / в рабочее положение.;" & _
                        "254*FE*Free Fall Protection*Защита от падения"


Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20
Global $Index[0], $Smart[0][13], $Smart1[0][13]
Global $i, $j, $p, $sPark, $sPark1, $Item[0]
Global $strVendorSpecific[0], $strVendorSpecificA[0], $k[0], $diskVendors[0][2], $Threshold[0][12], $ThresholdAll[0], $Porog[0]
Global $STR1[0][4]

$TTT = _StringExplode($sSMARTCodeTxt, ";")
ConsoleWrite('TTT  ' & UBound($TTT) & @CR)
For $s = 0 To UBound($TTT)-1
   _ArrayAdd($STR1, $TTT[$s], 0, "*")
Next

$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItems = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
For $diskVendor In $colItems
                 ConsoleWrite ("InstanceNameFor: " & StringReplace($diskVendor.InstanceName, '\','\\') &@CR)
                 _ArrayAdd($diskVendors, $diskVendor.InstanceName &'|'&StringReplace($diskVendor.InstanceName, '\','\\'))
Next

ConsoleWrite('STR1  ' & UBound($STR1) & @CR)

For $zzz=0 To UBound($diskVendors)-1
_Smart($diskVendors[$zzz][1])
Next
Func _Smart($zzz)

$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItems = $objWMIService.ExecQuery('SELECT * FROM MSStorageDriver_ATAPISmartData Where InstanceName="' & $zzz &'"', "WQL", 0x30)
       For $Item In $colItems
            $strVendorSpecific = $Item.VendorSpecific
;           _ArrayDisplay($strVendorSpecific,"Спецификация")
Next

   For $z = 2 to UBound($strVendorSpecific) - 1 Step 12
      _ArrayAdd($k, $strVendorSpecific[$z])
   Next

   _ArrayDisplay($k, "массив вытянутых значений")  ; массив всех полученных id значений у винчестера

For $j = 0 To UBound($STR1)-1
   For $jk = 0 To UBound($k)-1
  For $i = 2 to UBound($strVendorSpecific) - 1 Step 12

Select

  Case $strVendorSpecific[$i] =  $k[$jk]
      Select  ; вставляю дополнительную проверку на существование официального значения
      Case $strVendorSpecific[$i] = $STR1[$j][0]
           $sPark1 = $strVendorSpecific[$i] & '|'  & $strVendorSpecific[$i+1] & '|' & $strVendorSpecific[$i+2]& '|' & $strVendorSpecific[$i+3] & '|' & $strVendorSpecific[$i+4] & '|' & $strVendorSpecific[$i+5] & '|' & $strVendorSpecific[$i+6] & '|' & $strVendorSpecific[$i+7] & '|' & $strVendorSpecific[$i+8] & '|' & $strVendorSpecific[$i+9] & '|' & $strVendorSpecific[$i+10] & '|' & $strVendorSpecific[$i+11]
         If StringStripWS($sPark1, 8) <> 0 Then _ArrayAdd($Smart1, $sPark1)
      Case $strVendorSpecific[$i] <> $STR1[$j][0]
           $sPark1 = $strVendorSpecific[$i] & '|'  & $strVendorSpecific[$i+1] & '|' & 'rezerv' & '|' & $strVendorSpecific[$i+3] & '|' & $strVendorSpecific[$i+4] & '|' & $strVendorSpecific[$i+5] & '|' & $strVendorSpecific[$i+6] & '|' & $strVendorSpecific[$i+7] & '|' & $strVendorSpecific[$i+8] & '|' & $strVendorSpecific[$i+9] & '|' & $strVendorSpecific[$i+10] & '|' & $strVendorSpecific[$i+11]
         If StringStripWS($sPark1, 8) <> 0 Then _ArrayAdd($Smart1, $sPark1)
      Case Else
           $sPark1=''
      EndSelect
Case Else
     $sPark1=''
EndSelect
Next
Next
Next
  _ArrayDisplay($Smart1, 'Smart1', Default, '', Default, "1|2|3|4|5|Значение|7|8|9|10|11|12|raw")
Global $Smart1[0][13]

EndFunc
Специально убрал из списка часть значений, как наиболее часто встречающиеся.
Что не так делаю и как организовать такую проверку и подстановку?
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
массив $strVendorSpecific обрабатывается до проблемного места кода.
зачем еще раз сравнивать значения? к тому же, это просто сравнение строк-цифр, а не спец.параметров.
может быть указанный массив разбить уже на значения, а потом их подставлять. при этом сократить количество вложенных циклов проверки.
в общем, на мой взгляд, нужно переработать логику кода
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
это просто сравнение строк-цифр, а не спец.параметров.
Вообще-то это не просто сравнение цифр. Сравниваются id параметров. По той же ссылке на вики есть не все параметры. Я чуток добавил уже пару раз.
Получается, что у меня второй массив - id параметров конкретного винта, а первый массив - "официальный" список параметров.
На первом скрине отсутствует id 9. я его убрал из списка официальных. Видно на скрине 3. А на втором все 30 зарезервированных строк для id параметров. В эти 30 строк производители втискивают ту инфу, которыую считают нужной. На вики больше 60 параметров. Я дособирал вроде до 72. Но где гарантия, что завтра не найду ещё один параметр?
Вообще сравнивается первая колонка на третьем скрине со второй на втором и получается первый скрин
Может и нужно поменять логику. Но ты прав, до этой проверки все работало шустро. Конечно были недочеты, но с помощью форумчан подправил.
 

Вложения

  • смарт список параметров на 12 зарезервированных ячеек.jpg
    смарт список параметров на 12 зарезервированных ячеек.jpg
    88 КБ · Просмотры: 3
  • смарт массив реальных параметров конкретного винта.jpg
    смарт массив реальных параметров конкретного винта.jpg
    67.6 КБ · Просмотры: 4
  • смарт официальный список параметров.jpg
    смарт официальный список параметров.jpg
    436.3 КБ · Просмотры: 2
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
В цикле ты сравниваешь цифры, не ячейки. Это не сравнение точных параметров
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
не так выразился, извини. ты перебором сравниваешь цифры
Код:
Case $strVendorSpecific[$i] =  $k[$jk]

берешь из массива $k это одно число сравниваешь со всеми числами из $strVendorSpecific
а ведь числа могут быть одинаковы в разных ячейках. но они несут разный смысл.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
А вдруг? Массив К уже имеет необходимые данные. Зачем его опять сравнивать с исходным?
 
Верх