Tema: Re: get info from txt file
Autorius: Laimis
Data: 2013-11-22 02:58:46
CurrentUser rašė:
> Sveiki,
>
> Aš skaitau tą kodo syntaksę kaip kiniškus hieroglifus. Čia akivaizdu,
> kad trūksta bazinių pagrindų. Beje, jei teisingai supratau, 'awk' išvis
> yra skirtas Linuxui. Tai turiu prisipažinti, kad gal tik 1 kartą jo

Tikrai nebūtinai Linux'ui.
http://gnuwin32.sourceforge.net/packages/gawk.htm
http://code.google.com/p/gnu-on-windows/downloads/list?q=label:gawk

Nėra taip sudėtinga, kaip atrodo. Svarbiausia, kad būtų daugiau noro 
išmokti, praplėsti akiratį... :-)
Anyway.


> Gal bus įdomu pažiūrėti, o jūs seni vilkai gal ir patarimą duosit, kaip
> suoptimizuoti kodą, nors vis tiek dabar užsiimu tuo, kad čia reikia
> išvengti vartotojo įsikišimo (atidarant excelio failą ir

Iš karto duosiu vieną patarimą, net nenagrinėjęs giliau: kai deklaruoji 
kintamuosius, tai, panašu, klaidingai manai, kad jiems visiems eilutėje 
galima nurodyti vieną tipą. Iš tikrųjų taip nurodai tą tipą 
_tik_vienam_, paskutiniam kintamajam, o visi kiti kintamieji 
deklaruojami Variant tipo. Tai gali būti ir ganėtinai neefektyvu (bendru 
atveju Variant tipo reikėtų vengti; tik specifiniais atvejais jis yra 
naudingas) plius subtilios klaidos, elgesys.
Kiekvienam ne Variant kintamajam reikia nurodyti tipą atskirai.
Todėl viena deklaracijų eilutė iš:

Dim eqp, opr, dat, lai, lot, prd, mat As String

turi pavirsti:

Dim eqp As String, opr As String, dat As String, lai As String, lot As 
String, prd As String, mat As String

Arba dar geriau (skaitomumo ir stiliaus prasme) vienas kintamasis 
vienoje eilutėje:

Dim eqp As String
Dim opr As String
Dim dat As String
<...>

O kad tiek daug kintamųjų, tai juk gali susikurti savo duomenų 
struktūrą/tipą (UDT user data type):

Type T_MYTYPE
     eqp As String
     opr As String
     dat As String
     lai As String
     lot As String
     prd As String
     mat As String
     <...>
End Type

Dim udtVar as T_MYTYPE

udtVar.eqp = "one"
udtVar.opr = "two"
<...>



O pasigilinus į kodo esmę, tai sprendimas ganėtinai PRASTAS. Vos tik 
pasikeistų nors vienas parametras tame failiuke (įsiterptų koks naujas 
ar jų sumažėtų), vos tik kas pasislinktų per vieną simbolį ir VISKAS 
GRIŪNA. Nes viskas kietai įsiūta/fiksuota. Jei ESI TIKRAS, kad formatas 
negali kisti ir tikrai nekis, tai ir toks sprendimas tinka, tačiau iš 
tikrųjų reikėtų rašyti kodą taip, kad iš kiekvienos eilutės 
parametrai/skaičiai būtų išgliaudomi nepriklausomai nuo (absoliučios) 
pozicijos, tarpo simbolių kiekio ir kt sąlygų. Kiek įmanoma mažiau 
priklausomai.

Taigi, iš tikrųjų nusimatytų gana bjauriai parse'inti eilutes su Mid(), 
Left() ir if'ais. Arba, reikės pasimokyti... :-) Regular expressions.

Neaišku ar šis formatas (parametrų kiekio ir jų žymų prasme) — 
galutinis/apibrėžtas.
Jei apibrėžtas, tai bemaž visas kodas (praktiškai ant lėkštutės) 
atrodytų maždaug taip:

(References: Microsoft Visual VBScript Regular Expressions 5.5)

Sub DisplayTextFile()
     Dim sBuffer As String
     Dim oRE As New VBScript_RegExp_55.RegExp
     Dim oMatch As VBScript_RegExp_55.Match
     Dim oMatches As VBScript_RegExp_55.MatchCollection

     Dim vKey As Variant
     Dim dictVars As New Dictionary

     Dim oFSO As New FileSystemObject

     Const FILE_PATH As String = "F:\Printout.txt"

     If Not oFSO.FileExists(FILE_PATH) Then
         Exit Sub
     End If



     sBuffer = oFSO.OpenTextFile(FILE_PATH, ForReading, False).ReadAll

     oRE.Global = True
     oRE.IgnoreCase = True

     ' Date/Time
     oRE.Pattern = "\s+(Date|Time):\s+((\d?\d\/\d?\d\/\d\d)|(\d\d:\d\d 
(AM|PM)))\b"
     For Each oMatch In oRE.Execute(sBuffer)
         'Debug.Print oMatch.SubMatches(0), oMatch.SubMatches(1)
         dictVars(oMatch.SubMatches(0)) = oMatch.SubMatches(1)
     Next

     ' Temperatures:
     oRE.Pattern = 
"\s+(E[1-4]|D[1-5]|S1|A)\s+(ON|OFF)\s+(\d{1,3}\.\d)\s+(\d{1,3}\.\d)\b"
     For Each oMatch In oRE.Execute(sBuffer)
         'Debug.Print oMatch.SubMatches(0), oMatch.SubMatches(1), 
oMatch.SubMatches(2), oMatch.SubMatches(3)
         dictVars(oMatch.SubMatches(0) + "_On") = oMatch.SubMatches(1)
         dictVars(oMatch.SubMatches(0) + "_Ts") = oMatch.SubMatches(2)
         dictVars(oMatch.SubMatches(0) + "_Ta") = oMatch.SubMatches(3)
     Next

     ' Other Settings:
     oRE.Pattern = "\s+((Syn-\w+)|(Maschine (Speed|Load))|(Puller \d? 
?Speed)|(Prod (Temperature|Pressure ?\d?)))\s+(\d{1,3}\.\d{1,2}\b)"
     For Each oMatch In oRE.Execute(sBuffer)
         'Debug.Print oMatch.SubMatches(0), oMatch.SubMatches(7)
         dictVars(oMatch.SubMatches(0)) = oMatch.SubMatches(7)
     Next

     For Each vKey In dictVars.Keys
         Debug.Print vKey, dictVars(vKey)
     Next

End Sub


Belieka surašyti dictVars reikšmes į atitinkamas celes.
Eq, Op, Poz, Lot, Prod palieku pačiam pasipraktikuoti, kaip išsitraukti 
(be to prikabintas Printout.txt kažkoks padarkytas, tai neaišku, kaip 
ten tie laukai iš tikrųjų eina/išsidėstę)

> 2010 Express gali daryti tik VB Form aplication. nežinau kaip sukurti
> aplikaciją be formos, kad ji užsisuktų backgraund’e.
> Būsiu dėkingas sulaukęs feedback’o.

Visą šį kodą iš tikrųjų gali parašyti VBS (VBScript). Taip pat gali iš 
VBS'o (per scheduler'į) iškviesti excel'io macros'ą/VBA:
http://krgreenlee.blogspot.com/2006/04/excel-running-excel-on-windows-task.html