Was soll dein Programm auch sonst tun?
In der Funktion Start ist nur eine einmalige Wertzuweisung enthalten, die wird ausgeführt und dann ist Schluß. Mehr an Befehlen steht ja nicht da.
Wenn du durch das Array iterieren möchtest, musst du mit Schleifen arbeiten.
Beiträge von BugFix
-
-
Und hier die Lösung zum Ausblenden: https://autoit.de/index.php?page…3195#post243195
-
Jemand fragte heute nach der Möglichkeit Kommentare im Skript Auszublenden. Also habe ich diese Funktion mal erstellt.
- Das angehängte Skript CommentsDelHide.lua in den Ordner ..\AutoIt3\SciTE\LUA\ abspeichern.
- Die Datei ..\USER\SciTEUser.properties öffnen
- Oberhalb von:Code#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # START: DO NOT CHANGE ANYTHING AFTER THIS LINE #-#-#-#-#einfügen:
Code
Alles anzeigen# 49 Delete Comments command.name.49.*=Delete Comments command.mode.49.*=subsystem:lua,savebefore:yes command.is.filter.49.*.au3=0 command.49.*=CommentsDelete command.shortcut.49.*.au3=Ctrl+Shift+L # 48 Hide Comments command.name.48.*=Hide Comments command.mode.48.*=subsystem:lua,savebefore:yes command.is.filter.48.*.au3=0 command.48.*=CommentsHide command.shortcut.48.*.au3=Ctrl+Shift+HHabt ihr noch keine Einträge dort, ist die erste freie Nummer ( statt der 48 ) die 36.
In der Datei ..\AutoIt3\SciTE\LUA\SciTEStartup.lua am Ende folgenden Eintrag hinzufügen:
Ausblenden dann mit Ctrl+Shift+H (oder einem HotKey eurer Wahl, den ihr hier definieren könnt) im AutoIt-Skript.
Die Kommentare können wieder eingeblendet werden durch:
- Neu Laden der Datei (Menü Start) oder
- Klick auf ein anderes Tab in SciTE und zurückZum Löschen aller Kommentarzeilen den HotKey Strg+Shift+L (oder einem HotKey eurer Wahl) nutzen.
Edit:Strg+Shift+L solltet ihr nicht verwenden - der Shortcut ist vorbelegt zum Löschen von Zeilen, also ändern.
Das ist das Skript:
Spoiler anzeigen
Code
Alles anzeigen-- TIME_STAMP 2011-12-30 20:47:47 v 0.2 -------------------------------------------------------------------------------- -- CommentsDelHide() -- -- Ausblenden (Standard) oder Löschen von Kommentarzeilen im aktuellen Skript -- -- Ausgeblendete Kommentare werden wieder sichtbar durch Neuladen der Datei (per Menü Datei od. bei Wechsel auf anderen Tab und zurück) -- -- PARAMAETER..[optional]..: _fDelete - false=HIDE COMMENTS (Standard) / true=DELETE COMMENTS -------------------------------------------------------------------------------- function CommentsDelHide(_fDelete) if _fDelete == nil then _fDelete = false end local function IsComment(pos) local tComment = {1,2} if tComment[editor.StyleAt[pos]] == nil then return false else return true end end local function IsWS(pos) if editor.StyleAt[pos] == 0 then return true else return false end end local function GetRange(tTable) local tRange = {} iStart = '' if table.getn(tTable) == 0 then return nil end for i = 1, table.getn(tTable) do if iStart == '' then iStart = tTable[i] end if i < table.getn(tTable) then if tTable[i+1] ~= tTable[i] +1 then table.insert(tRange, {iStart, tTable[i]}) iStart = '' else if i+1 == table.getn(tTable) then table.insert(tRange, {iStart, tTable[i+1]}) break end end else table.insert(tRange, {tTable[i], tTable[i]}) end end return tRange end local function PreZero(sText, iMax) return string.rep('0', iMax - string.len(sText))..sText end editor:GotoLine(0) local n = 0 local tCommLines = {} while editor.LineCount > n do editor:GotoLine(n) if IsComment(editor.CurrentPos) then table.insert(tCommLines, n) elseif IsWS(editor.CurrentPos) then editor:WordRight() if IsComment(editor.CurrentPos) then n = editor:LineFromPosition(editor.CurrentPos) table.insert(tCommLines, n) end end n = n +1 end editor:BeginUndoAction() if _fDelete then if table.getn(tCommLines) > 0 then for i = table.getn(tCommLines), 1, -1 do editor:GotoLine(tCommLines[i]) editor:LineDelete() end end else local tRanges = GetRange(tCommLines) if tRanges == nil then print('!++ NO COMMENT LINES DETECT ++') end local max = string.len(tRanges[table.getn(tRanges)][2]) for i = 1, table.getn(tRanges) do print('++ HIDE LINE'..'....'..PreZero(tostring(tRanges[i][1]), max)..' TO '..PreZero(tostring(tRanges[i][2]), max)..' ++') editor:HideLines(tRanges[i][1],tRanges[i][2]) end end editor:EndUndoAction() end -- CommentsDelHide() function CommentsHide() CommentsDelHide() end function CommentsDelete() CommentsDelHide(true) end -
Lies das Array per _ExcelReadArray ein. Da gibt es den Parameter $iDirection mit dem du das regelst.
-
Deine Frage liefert leider keine Informationen... :wacko:
Von was für Kommentaren sprichst du?
Meinst du deine Kommentare im Skript? Ausblenden - Nein, alle Kommentare entfernen - Ja, machbar. -
Zu diesem Programm ist relativ wenig zu erfahren und einen Crack davon werde ich mir sicher nicht laden um herauszufinden, welche DB verwendet wird.
In den Dokus von Verwaltungssoftware, wo auch auf dieses Programm verwiesen wurde wird aber meist als Voraussetzung ein MSQL-Server genannt. Somit gehe ich mal stark davon aus, dass das Programm auch mit MSQL arbeitet.
Das Herumdoktorn über Klick-hier, Klick-da solltest du erst gar nicht in Erwägung ziehen. Solche Lösungen sind nur das letzte Mittel, wenn gar nichts geht.
Hast du überhaupt schon versucht mit dem AutoIt-Window-Info-Tool herauszufinden, ob die Controls deines Programms erkannt werden? Aber auch das ist nur 2-te Wahl.
Wenn hier eine bekannte DB im Einsatz ist, muß der Weg sein: Direkte Abfrage der gewünschten Daten aus der DB. Das ist sauber und schnell. Jede andere Lösung ist nur eine Krücke. -
Damit es im anderen Thread nicht übersehen wird, verlinke ich nochmal in einem extra Thread.
DebugToConsole/ ~MsgBox -
Habe den Thread mal hierher verschoben, mach auch mal eine Aussage zu deiner Gegenleistung, ein Kilo Heringssalat zu Silvester wär nicht schlecht.

Was fehlt:
Das verwendete Datenbanksystem. Auf die DB muß zugegriffen werden können um Abfragen zu gestalten, da ist es schon wichtig zu wissen, was ihr verwendet (MySQL, Firebird oder was auch immer).
Darauf basiert auch unsere Entscheidung: Kann ich überhaupt mit der DB umgehen und somit Helfen?
Am Besten gleich mal noch die Datenstruktur der Tabelle Artikel dazu packen. Vermutlich sind die Zusatzinfos nicht in dieser Tabelle abgespeichert sondern nur per Indexverweis. Da wäre es dann sinnvoll in der DB-Beschreibung nachzuschauen, wie diese Verknüpfung gestaltet ist.
Je mehr Info von dir kommt, desto größer ist auch die Wahrscheinlichkeit, dass dir geholfen werden kann. - z.Zt.: nahe null.
-
Ich habe noch kleine Änderungen im Post #4 vorgenommen.
Den Post von BasicOS werte ich mal als Info, dass eine neue LUA-Version released wurde.
Nun aber zum eigentlichen Kern dieses Threads - ich will euch teilnehmen lassen an meinem Lernen in LUA.
Heute:
RegExpPattern
Es gibt einen deutlichen Unterschied zu AutoIt: LUA bietet nativ keine Regexp-Engine. - Aber: LUA arbeitet mit verschiedenen Pattern-gestützten Funktionen. Ähnelt RegExp, weist aber auch einige markante Unterschiede auf.
Am Anfang habe ich oft geflucht, wenn es um das Erstellen von Pattern für LUA ging. Aber auch hier ist es ähnlich, wie in AutoIt: lange Probieren führt letztlich zur Erkenntnis.
Die Charakter Klassen sind ähnlich, wie bei AutoIt-RegExpCode
Alles anzeigen. all characters %a letters %c control characters %d digits %l lower case letters %p punctuation characters %s space characters %u upper case letters %w alphanumeric characters %x hexadecimal digits %z the character with representation 0Aber wir finden zwei bisher Unbekannte: %l und %u (Klein-/Großbuchstaben).
Damit kann man Pattern teilweise sehr vereinfachen.
Allerdings ist in diesem Zusammenhang auch anzumerken, dass es keine Möglickeit gibt per Schalter case-insensitiv zu prüfen (es gilt immer case-sensitiv). Somit muß ein Pattern, das "Func" in jeder Schreibweise erkennen kann, so aussehen:
AutoIt: "(?i)func"
LUA: "[Ff][Uu][Nn][Cc]"
Das sieht nun nach mehr Schreibarbeit aus, wenn z.B. der Suchbegriff recht lang ist. Aber wozu gibt es denn Funktionen? Ich verwende dazu folgende Funktion:Codefunction InSens(s) s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.upper(c),string.lower(c)) end) return s endDamit sieht das obige Pattern dann so aus: InSens("func")
Hier treffen wir auf: string.gsub(), einer StringReplace-Funktion. Hiermit suche ich nach einem Match für mein Pattern (hier "%a" = Buchstaben). Da ich als dritten Parameter eine Funktion einsetze, die ich genialerweise direkt im Aufruf erstellen kann, bildet die Funktion den Ersatzstring [ Match-Großbuchstabe Match-Kleinbuchstabe ] und ersetzt den Treffer damit. In einem optionalen 4-ten Parameter kann die Anzahl der Ersetzungen festgelegt werden.Die anderen Charakterklassen sind bekannt und brauchen keiner Erklärung.
Bei den Quantifiern bietet LUA uns zusätzlich das "- 0 oder mehr Vorkommen" an. Also identisch zu "*" ? Keineswegs. Laut Doku besteht der entscheidende Unterschied darin, dass "-" immer den kürzest möglichen Match wählt, während "*" immer auf die längste Sequenz zugreift.
Und dann gibt es noch ein echtes Schmankerl: %bxy
Damit lassen sich sich "balanced strings", also ausgewogene Strings ermitteln. xy geben Start- und Endzeichen an. Üblicherweise findet es Anwendung für: '%b()', '%b[]', '%b%{%}', oder '%b<>', aber auch alle anderen Zeichen können Verwendung finden.
Wichtig: Auf diese Matches können keine Quantifier angewendet werden.
Das war übrigens das entscheidende Mittel um die Variablenerkennung von Array-Variablen zu realisieren.Wer hier nach der Pipe sucht um eine ODER-Abfrage zu gestalten wird enttäuscht. Das geht nicht. Da die Stringverarbeitung in LUA gefühlte 10-mal schneller abläuft als in AutoIt (mal ein Testskript zum Messen erstellen ;)) ist es aber kein Problem statt ODER verschiedene Pattern in einem Table (Array) abzulegen und dann abzuarbeiten.
Anchor: Auch hier können wir Anker für Match am Stringanfang (^) und am Stringende ($) setzen.
Capturing: Das Capturing ist weitestgehend analog zu dem in AutoIt. Aber was für mich völlig neu war: Verwendung des Captures im Pattern selbst.
Bsp.:
Wir haben einen String: Peter sagt: "Das war's dann"!
Um den String einer Variablen zuzuweisen kommt man bei AutoIt schon ins Schwitzen wegen der Quotierung. Hier haben wir aber einen weiteren Stringbegrenzer, die doppelte eckige Klammer:
s = [[Peter sagt: "Das war's dann"!]]
Nun soll der Bereich zwischen den doppelten Anführungszeichen gefunden werden.
posStart, posEnd, 1stCapture, 2ndCapture = string.find(s, "([\"'])(.-)%1")
Da Pattern in LUA generell wie Strings behandelt werden, gilt auch im Pattern, dass Quota escaped werden müssen (anders als magic characters, die mit % maskiert werden, verwendet man dabei "\".
Der erste Ausdruck sucht nach einem Quotierungszeichen im String und speichert das Ergebnis in %1. Dem kann jedes Zeichen, beliebig oft (kürzestes Vorkommen) folgen. Anschließend muß das gleiche Quotierungszeichen, wie beim ersten Fund, folgen. Dazu wird dann direkt mit %1 darauf verwiesen.
string.find gibt als erste zwei Parameter die Trefferpositionen des Matches zurück. Position 3 enthält den ersten Match (oder nil wenn kein Treffer), sind mehrere Matches vorhanden, wird jeder Treffer als weiterer Wert zurückgegeben. Das gilt es zu beachten, um auch das gewünschte Ergebnis, hier 2ndCapture, zu verwenden.
Lassen wir uns 2ndCapture ausgeben, erhalten wir, wie gewünscht: Das war's dannUnd damit schließe ich für den Moment und wünsche euch ein schönes Restjahr.
-
nicht auch editor:GetCharAt(iCaret) verwenden?
Macht der Gewohnheit, so hatte ich angefangen in LUA.

Und statt dem GoToPos,
Das GoToPos verwende ich hier um die vorherige Auswahl ( die ich mit GetCharAt gar nicht brauchen würde
) wieder aufzuheben, rein optische Geschichte.Edit: Ahh, jetzt hab ich PositionFromLine() mit LineFromPosition() verwechselt. - Da hast du natürlich total recht, Danke für die Tipps.
Edit2: Grad probiert: editor:GetCharAt() funktioniert nicht "Pane function / readable property / indexed writable property name expected"
Edit3:
Habs gefunden, andere Syntax:
char = editor.CharAt[pos] -
Ich habe die Variablenerkennung für die Debugging-Funktionen (Debug To Console/MsgBox) nochmal überarbeitet.
Es werden jetzt alle Variablenkonstrukte in AutoIt erkannt, seien sie auch noch so verkapselt.
Allerdings habe ich die Erkennung von Array-Variablen auf 4D begrenzt, das sollte reichen.
Objektvariablen (sofern sie mit Methoden oder Properties verknüpft sind) werden ignoriert, da nicht feststellbar ist ob auch ein Wert zurückgegeben wird, der darstellbar ist.
Auch die (äußerst schlampige) Syntax in AutoIt, dass zwischen den Klammernpaaren von Arrays beliebig viele Leerzeichen liegen dürfen ist berücksichtigt.
Was ich aber rausgelassen habe, ist die Möglichkeit eine einzelne Variable über mehr als eine Zeile darzustellen - das ist mir zu pervers.
Dieses ist die Funktion zur Erkennung der Variablen:
Spoiler anzeigen
Code
Alles anzeigenfunction GetVarFromCursor() local iCaret = editor.CurrentPos local iTmp = iCaret local sSel = string.char(editor.CharAt[iCaret]) -- Zeichen auslesen if (string.byte(sSel) == 13) or (sSel == ' ') or (sSel == ',') then -- es folgen Zeilenumbruch, Leerzeichen oder Komma --> Var muss links stehen iCaret = iCaret -1 end local sLeft = string.char(editor.CharAt[iTmp-1]) local iLine = editor:LineFromPosition(iCaret) -- Zeilennummer local iLine1stPos = editor:PositionFromLine(iLine) -- Spaltenposition Zeilenanfang local iDiffPos = iCaret - iLine1stPos +1 -- Position Cursor in Zeile local sLine = editor:GetLine(iLine) -- Text der Zeile auslesen local tPatternArray = {'%$[%w_]+%s*%b[]%s*%b[]%s*%b[]%s*%b[]','%$[%w_]+%s*%b[]%s*%b[]%s*%b[]','%$[%w_]+%s*%b[]%s*%b[]','%$[%w_]+%s*%b[]'} -- erkennt Variablen mit folgenden Array-Klammer-Paar(en), bis 4D-Array (inkl. dessen gesamten Inhalt) local sPatternNormal = '%$[%w_]+%s*[^[]' -- erkennt nur Nicht-Array-Variablen function SearchVar(_sLine, _sPattern, _iCursor) -- Funktion zur Pattern-gestützten Variablensuche erstellen local tVars = {} -- table Variablen Matches local iMatchStart iMatchEnd = 0 -- Position Match while true do -- Suche nach allen Variablen laut Pattern (Array- oder Nicht-Array-Variable) iMatchStart, iMatchEnd = string.find(_sLine, _sPattern, iMatchEnd +1) if iMatchStart == nil then break end table.insert(tVars, {iMatchStart, iMatchEnd}) end if table.getn(tVars) > 0 then for i = 1, table.getn(tVars) do if ( _iCursor >= tVars[i][1] ) and ( _iCursor <= tVars[i][2] ) then return string.sub(_sLine, tVars[i][1], tVars[i][2]) end end end return nil end local sVarUnderCursor -- zum Speichern der erkannten Variable for i = 1, 4 do -- mit allen 4 Array-Pattern (4D bis 1D) prüfen ob Cursor in entsprechender Arrayvariable sVarUnderCursor = SearchVar(sLine, tPatternArray[i], iDiffPos) if sVarUnderCursor ~= nil then return sVarUnderCursor end -- Treffer - Variable wird zurückgegeben end if sVarUnderCursor == nil then -- kein Treffer bei Arrayvariablen, Prüfen ob Cursor an einem Komma ohne Variablenberührung steht local fLeftVar = false fRightVar = false if string.find(sLeft, '[%w_$]') ~= nil then fLeftVar = true -- links ist Variable möglich else if sSel == '$' then fRightVar = true end end if not fLeftVar and not fRightVar then return '' end sVarUnderCursor = SearchVar(sLine, sPatternNormal, iDiffPos) -- Nicht-Arrayvariable an Cursorposition ? if sVarUnderCursor == nil then return '' end -- kein Treffer: Return Leerstring end if string.find(sVarUnderCursor, '%.$') then return '' end -- Variable ist Objekt-Variable sVarUnderCursor = string.sub(sVarUnderCursor, string.find(sVarUnderCursor, '%$[%w_]+')) return sVarUnderCursor end -- GetVarFromCursor()
Am einfachsten in die bestehende "..\SciTE\LUA\AutoItTools.lua" diese Funktion einfügen. Unbedingt vor der Funktion: DebugMsgBoxAdd() einfügen.
Anschließend in den Funktionen: DebugMsgBoxAdd() und DebugConsoleWriteAdd() folgende Änderung vornehmen:Codefunction AutoItTools:DebugMsgBoxAdd() --~ local word = self:GetWord2() local word = GetVarFromCursor()Codefunction AutoItTools:DebugConsoleWriteAdd() --~ local word = self:GetWord2() local word = GetVarFromCursor()Oder einfach eure AutoItTools.lua gegen die im Anhang austauschen.
Viel Spaß dabei.Edit 29.12.2011: Noch zwei Ausnahmen eingefügt ( Cursor hinter schließender eckiger od. runder Klammer, die an Variable grenzt ).
Edit 31.12.2011: progandys Anregungen übernommen -
_GUICtrlListView_AddItem() iParam auf 3 oder 5 setzte
ItemParam immer > 2000 wählen, dann kollidierst du nicht mit den Control-ID's. Ist ein nicht dokumentierter Fehler.
Willst du "5" setzen, einfach:
$Shift = 2000
setzen: 5 +$Shift
lesen: _GuiCtrlListView_GetItemParam(...) -$Shift -
Ich bin im Besitz einer UDF in der AutoitObject eingebetet ist. Nun mochte ich gern die UDF davon befreien, hab aber keine Ahnung wie ich das nun bewirkstelligen könnte, damit diese trotzdem lauffähig bleibt. Könte mir jemand bitte dazu einen Rat geben

Falls AutoItObject in der UDF genutzt wird, ist das Vorhaben sinnlos.
Falls nicht, woher sollen wir wissen wie deine UDF aussieht - Glaskugel ist grad zur Reparatur...
-
wie aus diesen floats (Fließkommazahlen) = "Frohe Weihnachten" wird
Im Speicher wurden Floats mit Werten hinterlegt. Auf diesen Speicherplatz wird mit einem Pointer verwiesen. Nun erstellt man eine Struktur, die Zeichen aufnehmen soll. Dann wird dieser Struktur gesagt, dass die Werte unter dem vorab erstellten Pointer zu finden seien. Die Zeichenstruktur weiß ja nicht, dass der Speicherplatz nicht aus Zeichen befüllt wurde, kann ihr ja auch egal sein. Die Daten werden als Zeichen interpretiert und ergeben in diesem Fall "Frohe Weihnachten". Warum? Natürlich hat Andy den Weg vorher genau andersrum genommen, um den String in die Zahlen zu "verwandeln".
-
Nochmal Autoit wurde doch erstellt um möglichst einfach zu sein, wieso kam man denn jetzt auf die Idee, dort DllStruct Funktion mit einzubinden, wobei findet es in Autoit am meisten eine Verwendung für ?
Wie Andy schon sagte: Entweder im Zusammenhang mit Dll oder in anderen speziellen Fällen (z.B. wenn du nur einen Integer besetzen kannst, wie bei _GUICtrlListviewSetItemParam, aber einen ganzen Schwung an Daten unterbringen mußt - da kommst du um Strukturen, hier einen Integer-Pointer der auf die eigentlichen Daten verweist, nicht herum.) -
So ein Schlingel. der Andy

-
Dein Mikro ist sehr wahrscheinlich ein Kondensatormikro. Diese haben ein offenes Feld. Neben den Schallwellen beeinflussen auch die körpereigenen elektromagnetischen und kapazitiven Felder dein Mikro. Dieser Einfluß ist relativ gering, bei absoluter Stille aber durchaus als Grundrauschen hörbar.
-
Angewohnheit aus einer anderen (nicht zwingend höheren) Sprache kann das durchaus sein. Wenn du mit reinen Datentypen arbeitest, fällt auch das Errorhandling etwas einfacher aus.

-
Zitat
Und ansonsten ist es auch als ein Art Angeberei hier zu verstehen wenn ich in einem sourcecode Variablen Inhalte als Struct eingebettet sehe, wobei es eigentlich nicht nötig tut

Keinesfalls würde ich das so sehen. Die Tatsache, dass AutoIt weitestgehend mit einem einzigen Datentyp (variant) arbeitet, ist nicht unbedingt immer von Vorteil. Bei Verwendung von Strukturen ist man gezwungen Datentypen einzuhalten und aus einem Zahlenstring kann dann nicht einfach ein Integer werden - String bleibt String. -
Dem ist im Wesentlichen nichts mehr hinzuzufügen.

Wenn du sehen möchtest, was man ausserhalb von DLL mit Strukturen anstellen kann, schau dir mal dieses hier an.