Ich bin da voll bei Andy. In meinem Firmenumfeld genieße ich den Vorteil, dass ich als einziger im EDV-Bereich agiere und auch Programme für die Firma schreibe. Da ich mit allen Arbeitsgängen vertraut bin, kann ich aus der Sicht des Anwenders programmieren.
Bsp.
Unsere Fa. ist recht klein und sämtliche Buchhaltung geht über ein Steuerbüro. Wir erstellen nur Ausgangsrechnungen und registrieren Zahlungseingänge. Über viele Jahre wurden immer zusätzliche Kopien der Rechnungen ausgedruckt und am Monatsende zum Steuerbüro gebracht. Die durften den Kram (ca. 300-500 Rechnungen pro Monat) dann händisch erfassen.
Ich hab dann mal angefragt, ob deren DATEV-Programm auch den Import von Daten ermöglicht und in welcher Form das sein müsste.
Nach den Anforderungen habe ich dann ein SQL-Query erstellt, zum Export der Monats-RE in eine dbf-Datei. Diese habe ich dann (natürlich mit AutoIt ) in die DATEV-importierbare Form gegossen.
Um hier Fehler auszuschließen, habe ich auch gleich im Vorfeld nach möglichen variablen Größen gefragt und diese dann über eine INI festgelegt.
Das sind z.B. bei vereinzelten Kunden abweichende Werte: KDNr=Buchungskonto;Steuersatz
Das läuft jetzt schon ca. 10 Jahre und hat bestimmt einigen Bäumen das Leben gerettet.
Beiträge von BugFix
-
-
Meinst Du damit die mit "ToolbarWindow32" benannte, oder die Menüs im "SciTEWindow"?
Ich hab doch extra alle erreichbaren Fensterklassen aufgezählt ("ToolbarWindow32" gehört dazu). Die Menüleiste, wenn du nicht die Lokalisierungsdatei eingefügt hast, sieht das, wie von dir benannt aus:
In meiner SciTE-Version 1.79 sieht das zwar etwas anders aus: "File | Edit | Search | View | Tools | Options | Language | Buffers | Help"
- gehört nicht zu den erreichbaren Fensterklassen.
Wenn ich das richtig verstanden habe, müßte das Basis-Programm "SciTE" mit entsprechenden Ergänzungen nach dem Muster "SciTE_Starter.au3" -> https://github.com/BugFix/AutoIt-…iTE_Starter.au3 in eine neue exe gebracht werden, um dann als angepasste Version z.B. als "SciTE_spez.exe" verwendet werden zu können.
Das könnte man machen - alle Änderungen in der Source vornehmen und ein eigenes SciTE kompilieren. Aber das ist für mich nicht praktikabel.
Ich versuche lieber AddOns zu erstellen, die zusätzliche Funktionalität für die von den meisten Usern genutzte SciTE-Version bringt, aber eben nur wenn jemand dies explizit möchte auch aktiviert wird.
Ein direkter Eingriff in die Menüleiste ist daher nicht realisierbar.Aber auch die greifbaren Fenster haben ihre Tücken. Du kannst z.B. mit der Toolbar-UDF aus AutoIt einen eigenen Button hinzufügen - aber den bekommst du nur beim Drüberfahren mit der Maus in Umrissen zu sehen und nach dem Neuzeichnen des SciTE Fensters ist er kpl. verschwunden. Man müsste wohl Prepaint und Postpaint Events abfangen und ein Neuzeichnen initialisieren. Da habe ich mich jetzt aber noch nicht reingekniet.
Meine SciTE_Starter.au3 ist eigentlich nur eine Hilfe, um verschieden SciTE-Varianten auszuprobieren ohne sich dabei die SciTEUser.properties zu zerschießen (Es gibt nur einen Pfad für diese Datei, der von jeder (installierten) SciTE-Variante/Version genutzt wird.)
-
ja hört sich nach einem Kontext der ersten Schreibmaschinen an
Kann auch eine Fehlerinnerung sein, aber ich meine auch diesen Begriff in meinem Schreibmaschinenkurs (vor 45 Jahren) gehört zu haben.
-
ich hab mal ein wenig mit diesem "hook" Zeug rumgespielt.
Danke dir, werde ich mir mal zu Gemüte führen.
-
Ich hatte ganz vergessen, dass ich ja bei meinem Internet Provider einen Onlinespeicher habe. Darauf habe ich mal ein Netzlaufwerk eingerichtet, ergibt dann \Device\1&1MiniRdr\;O:1\1&1\SmartDrive.
-
Exakt
Vielen Dank für Deine Mühe.
Und jetzt genieße die Jeckenzeit oder geh ins Exil (je nachdem, wo du dich verortest - ich definitiv bei Letzterem )
-
Ok bei einem tatsächlichen Netzlaufwerk (auf nen Samba-Server) bei mir bringt mir deine Funktion das:
Wäre das dann in der direkten Adressierung \\nas.lan\adm ?
-
Nur eine Vermutung: Wenn du ein Netzlaufwerk eingerichtet hast, dann gilt das erst einmal nur für den User.
Stimmt genau, habe gerade mal eine Admin-Konsole geöffnet und versucht in das Laufwerk zu wechseln - wird nicht gefunden.
Das erklärt mir also warum das so ist. Zumindest kann ich das ja mit der Funktion aufdröseln.
Für mich war jetzt nur von Interesse, was passiert, wenn eine tatsächliche Netzlaufwerksverknüpfung durch _WinAPI_QueryDosDevice geschleust wird. Ich vermute mal ähnlich wie \Device\LanmanRedirector\;F:000000000009882e\localhost aber eben nicht mit localhost als Fortführung.
-
Hi,
wie ich feststellen musste, kommen nicht alle Programme mit Netzlaufwerksverknüpfungen auf lokale Ordner klar.
Ich habe z.B. gemappt: C:\Users\BugFix\Documents\_F auf Laufwerk F:Ich habe mir nun eine Funktion erstellt, die den korrekten Pfad zurück gibt.
Habe leider keine echten Netzlaufwerke zum Testen, was dabei raus kommt. Wenn ihr bitte mal probieren könnt.
EDIT: Die Funktion ist jetzt so geändert, dass (hoffentlich) alle Mappings aufgelöst werden können.
AutoIt
Alles anzeigen#include <WinAPIFiles.au3> ; #FUNCTION# ======================================================================================= ; Name ..........: _PathGetUnmapped ; Description ...: Resolving network links in paths to absolute paths ; Syntax ........: _PathGetUnmapped($_sPath) ; Parameters ....: $_sPath - The path to be checked. ; Return values .: The resolved path or the original path. ; Author ........: BugFix ; Remarks .......: Requires <WinAPIFiles.au3> ; ================================================================================================== Func _PathGetUnmapped($_sPath) If StringLeft($_sPath, 2) = '\\' Then Return $_sPath ; qualified network path Local $aPath = StringRegExp($_sPath, '([A-Za-z]:)(.+)', 1) Local $vReturn = _WinAPI_QueryDosDevice($aPath[0]) If StringRegExp($vReturn, '^\\Device\\LanmanRedirector') Then If StringInStr($vReturn, 'localhost') Then $vReturn = StringReplace(StringRegExpReplace($vReturn, '\\Device\\LanmanRedirector\\[^\\]+\\localhost\\', ''), '$', ':') Else $vReturn = '\' & StringRegExp($vReturn, '(\\Device\\LanmanRedirector\\;[^\\]+)(.+)', 1)[1] EndIf Return $vReturn & (UBound($aPath) = 2 ? $aPath[1] : '') Else $vReturn = StringRegExp($vReturn, '(\\Device\\[^\\]+\\;[^\\]+)(\\.+)', 1) EndIf If IsArray($vReturn) Then Return '\' & $vReturn[1] & (UBound($aPath) = 2 ? $aPath[1] : '') Else Return $_sPath EndIf EndFunc
-
Und Fehler sollten eigentlich von jedem Kommandozeilenprogramm nicht auf stdout ausgeben sondern auf stderr.
Es ist ja nicht so, dass mir das neu wäre. Aber es gibt so Tage...
git ist kein Befehl der cmd.exe sondern ein eigenständiges Programm. Es ist daher unsinnig es erst indirekt über den Umweg @comspec & "/c " aufzurufen.
War meinem C&P geschuldet, da ich die CmdLineRead-Funktion schon hatte. Aber klar, ohne Zweifel unsinnig.
Du musst StdOutRead() nicht unbedingt in einer Schleife ausführen. Es würde auch reichen den Prozess rödeln zu lassen und mit ProcessWaitClose() auf dessen Ende zu warten. Danach nur einmal StdOutRead() auf die Prozess-ID.
Passt.
-
2 Funktionen:
_FileListToArray
_ArrayToString
-
Ich führe in einer Konsole im Hintergrund git-Befehle aus und verwerte dann deren Rückgabe in die Konsole. Das klappt auch, solange ein Repo vorhanden ist.
Nun habe ich folgendes, für mich nicht erklärbares, Verhalten:
Wende ich eine git-Befehl in einem Ordner ohne Repository an, bekomme ich einen Fehler (ist auch gewünscht zur Auswertung) den ich jedoch nicht auffangen kann. Die Fehlermeldung landet in der Konsole des Aufrufs (SciTE) und die Return-Variable bleibt leer.AutoIt
Alles anzeigen#include <AutoItConstants.au3> ; wechseln in Verzeichnis ohne Repo FileChangeDir('C:\Users') $Status = _GitStatus() ConsoleWrite('<< Status >>' & @CRLF & $Status & @CRLF) Func _GitStatus() Return _CMDLineRead('git status') EndFunc Func _CMDLineRead($_sCMD) Local $PID = Run(@ComSpec & " /c " & $_sCMD, "", @SW_HIDE, $STDOUT_CHILD) Local $sLine, $sOutput = '' While 1 $sLine = StdoutRead($PID) If @error Then ExitLoop $sOutput &= $sLine WEnd Return $sOutput EndFunc
-
Der Hook reagiert auch auf Scite
Ja, Danke.
Aber leider ist die Reaktion bei Verwendung des Split-Screen-Dialogs etwas ernüchternd:
Ohne Handle kann ich leider nicht erkennen, ob das von SciTE ausgelöst wurde.
EDIT: Als Alternative bliebe natürlich: Mit dem obigen Ergebnis könnte das von SciTE ausgelöst worden sein - Also löse ich eine Prüfung aus.
Aber ... nee, geht nicht - ich prüfe ja derzeit sowieso mit AdlibRegister im 350 ms Intervall und WinGetPos() liefert keine Änderung!
Also: Auf Verdacht neu zeichnen als letzte Alternative.INFO: Habe das auch mal im EN-Forum gepostet https://www.autoitscript.com/forum/topic/21…ls_1529931_menu
-
vll hilft dieser beitrag von guiness https://www.autoitscript.com/forum/topic/15…napi-functions/
Hätte ich vllt. erwähnen sollen: Shellhook hatte ich bereits probiert. Ich habe dafür aber ausschließlich Bsp. für selbst erstellte Fenster gefunden (damit funktioniert das) - mit Fremdfenstern habe ich bisher keinen Erfolg gehabt.
-
Bei Win 11 kann ich mit Maus über Max-Button auf dem aufpoppenden Fenster auswählen, wie der Bildschirm geteilt wird und welche Position mein Fenster dann einnimmt. Das ist grundsätzlich erst mal schön.
Mein Problem:
Wie hier erwähnt, schreibe ich ein AddOn zur Nutzung von Git in SciTE. Unter anderem habe ich in die SciTE-Toolbar Icons integriert zur Anzeige von Status und Anzahl von untracked files (oder modified).
Sieht dann so auskein Repo vorhanden Repo ist aktuell Repo - 7 Dateien untracked Repo - >9 Dateien untracked
Ich zeichne die Icon mit WinAPI-Funktionen in die Toolbar. Bei Neuzeichnen des SciTE-Fensters geht das natürlich verloren und muss ebenfalls neu gezeichnet werden.
Das kann ich grundsätzlich prima abfangen, indem ich einen Größenvergleich (pos/size) des Fensters durchführe und bei Änderung neu zeichne. Fenster verschieben / Größe ändern / Minimieren / Maximieren - alles führt zur Änderung bei WinGetPos.
Nur halt die Größenänderung über den Max-Button, wie anfangs beschrieben. ändert die auf diese Weise abgefragte Fenstergröße nicht.Habt ihr eine Idee?
Hier mein Skript ( P.S. - Das Skript muss von Hand abgeschossen werden, ist zum Dauerlauf gedacht )
AutoIt: SciTE_DrawGitStatus.au3
Alles anzeigen#include <GuiToolbar.au3> #include <WinAPIShellEx.au3> ;--------------------------------------------------------------------------------------------------- Global $ICO = @ScriptDir & '\ico\' Global $mIcon[] $mIcon['IsRepo'] = $ICO & 'git_hasrepo.ico' $mIcon['NoRepo'] = $ICO & 'git_norepo.ico' $mIcon['Changing'] = $ICO & 'git_repo-w-changings.ico' For $i = 1 To 9 $mIcon[$i] = $ICO & $i & '_16.ico' Next $mIcon[99] = $ICO & '9+_16.ico' ; >9 files ;--------------------------------------------------------------------------------------------------- Global $gm_SciTE[] $gm_SciTE.hWnd = 0 $gm_SciTE.ExistsLast = 0 $gm_SciTE.ExistsCurr = 0 $gm_SciTE.WinArrayLast = 0 $gm_SciTE.WinArrayCurr = 0 $gm_SciTE.bReDraw = False $gm_SciTE.aStatusIcon = 0 $gm_SciTE.aCounterIcon = 0 $gm_SciTE.StatusIcon = Null $gm_SciTE.CounterIcon = Null ;--------------------------------------------------------------------------------------------------- _SciTEToolBar_DrawIconGitStatus('Changing') _SciTEToolBar_DrawIconGitCounter(99) ;--------------------------------------------------------------------------------------------------- _CheckSciTE() AdlibRegister(_CheckSciTE, 1000) While True Sleep(5000) WEnd Func _End() AdlibUnRegister(_CheckSciTE) Exit EndFunc Func _CheckSciTE() If ProcessExists("SciTE.exe") Then Local $hScite, $hToolbar, $hStatusbar _GetSciTEhWnd($hScite, $hToolbar, $hStatusbar) $gm_SciTE.ExistsCurr = 1 If $gm_SciTE.ExistsLast = 0 Then $gm_SciTE.ExistsLast = 1 $gm_SciTE.hWnd = $hScite AdlibRegister(_CheckReDraw, 350) EndIf Else $gm_SciTE.ExistsCurr = 0 If $gm_SciTE.ExistsLast = 1 Then $gm_SciTE.ExistsLast = 0 $gm_SciTE.hWnd = 0 AdlibUnRegister(_CheckReDraw) EndIf EndIf EndFunc Func _CheckReDraw() ; check if size/pos has changed (after min/max the pos has also changed) $gm_SciTE.WinArrayCurr = WinGetPos($gm_SciTE.hWnd) Local $bChanged = False If IsArray($gm_SciTE.WinArrayLast) Then $bChanged = _WinSizeDiff() ; if Diff returns: True Else $bChanged = True EndIf $gm_SciTE.bReDraw = $bChanged _ReDraw() EndFunc Func _WinSizeDiff() If ($gm_SciTE.WinArrayLast[0] <> $gm_SciTE.WinArrayCurr[0]) Or _ ($gm_SciTE.WinArrayLast[1] <> $gm_SciTE.WinArrayCurr[1]) Or _ ($gm_SciTE.WinArrayLast[2] <> $gm_SciTE.WinArrayCurr[2]) Or _ ($gm_SciTE.WinArrayLast[3] <> $gm_SciTE.WinArrayCurr[3]) Then Return True Else Return False EndIf EndFunc Func _ReDraw() If Not $gm_SciTE.bReDraw Then Return Else AdlibUnRegister(_CheckReDraw) _SciTEToolBar_DrawIconGitStatus($gm_SciTE.StatusIcon) _SciTEToolBar_DrawIconGitCounter($gm_SciTE.CounterIcon) $gm_SciTE.WinArrayLast = $gm_SciTE.WinArrayCurr AdlibRegister(_CheckReDraw, 350) EndIf EndFunc Func _SciTEToolBar_DrawIconGitStatus($_sStatus) ; 'IsRepo', 'NoRepo', 'Changing' $gm_SciTE.aStatusIcon = _SciTEToolBar_DrawIcon($mIcon[$_sStatus], True) $gm_SciTE.StatusIcon = $_sStatus EndFunc Func _SciTEToolBar_DrawIconGitCounter($_iCounter) ; 1,2,3,4,5,6,7,8,9,99 0-Deletes the counter Icon If $_iCounter = 0 Then _SciTEToolBar_DeleteDrawedIcon($gm_SciTE.aCounterIcon) $gm_SciTE.aCounterIcon = 0 $gm_SciTE.CounterIcon = Null ElseIf $_iCounter = Null Then Return Else $gm_SciTE.aCounterIcon = _SciTEToolBar_DrawIcon($mIcon[$_iCounter], True, 16) $gm_SciTE.CounterIcon = $_iCounter EndIf EndFunc Func _SciTEToolBar_DrawIcon($_sPathIcon, $_bDeleteBG=True, $_xRel2LastTBItem=Null) Local $hScite, $hToolbar, $hStatusbar ; get SciTE handles _GetSciTEhWnd($hScite, $hToolbar, $hStatusbar) If @error Then Return SetError(1) Local $aPadding = _GUICtrlToolbar_GetPadding($hToolbar) Local $xPad = $aPadding[0] Local $aLastItem = _GUICtrlToolbar_GetButtonRect($hToolbar, _ _GUICtrlToolbar_IndexToCommand($hToolbar, _GUICtrlToolbar_ButtonCount($hToolbar)-1)) Local $x = $_xRel2LastTBItem = Null ? $aLastItem[2] : ($aLastItem[2] + $xPad + $_xRel2LastTBItem) Local $hDC = _WinAPI_GetDC($hToolbar) If $_bDeleteBG Then ; Delete last icon by overwriting Local $a[] = [$x+$xPad, 3, 16, 16] _SciTEToolBar_DeleteDrawedIcon($a, $hDC) EndIf Local $hIcon = _WinAPI_ShellExtractIcon($_sPathIcon, 0, 16, 16) Local $aIconDrawed[] = [$x+$xPad, 3, 16, 16] _WinAPI_DrawIconEx($hDC, $x+$xPad, 3, $hIcon, 16, 16) _WinAPI_DestroyIcon($hIcon) _WinAPI_DeleteDC($hDC) Return $aIconDrawed EndFunc Func _SciTEToolBar_DeleteDrawedIcon($_aIcon, $_hDC=Null) ; $_aIcon returned from _SciTEToolBar_DrawIcon Local $tRect = DllStructCreate($tagRect), $bDelDC = False $tRect.Left = $_aIcon[0] $tRect.Top = $_aIcon[1] $tRect.Right = $_aIcon[0] + $_aIcon[2] $tRect.Bottom = $_aIcon[1] + $_aIcon[3] If $_hDC = Null Then Local $hScite, $hToolbar, $hStatusbar ; get SciTE handles _GetSciTEhWnd($hScite, $hToolbar, $hStatusbar) If @error Then Return SetError(1) $_hDC = _WinAPI_GetDC($hToolbar) $bDelDC = True EndIf Local $hBrush = _WinAPI_CreateSolidBrush(0xF0F0F0) _WinAPI_FillRect($_hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) If $bDelDC Then _WinAPI_DeleteDC($_hDC) EndFunc Func _GetSciTEhWnd(ByRef $_hScite, ByRef $_hToolbar, ByRef $_hStatusbar) $hActive = WinGetHandle('[ACTIVE]') $aResult = DllCall('user32.dll', "int", "GetClassNameW", "hwnd", $hActive, "wstr", "", "int", 4096) If Not @error And $aResult[2] = 'SciTEWindow' Then $_hScite = $hActive $_hToolbar = ControlGetHandle($_hScite, '', '[CLASS:ToolbarWindow32; INSTANCE:1]') $_hStatusbar = ControlGetHandle($_hScite, '', '[CLASS:msctls_statusbar32; INSTANCE:1]') Return 1 Else Return SetError(1) EndIf EndFunc
-
Das sagt erst mal das Wesentliche dazu.
Für die SciTE-User:
Wenn git installiert ist, können alle Befehle in der SciTE-Konsole ausgeführt werden.
Ich werde mich mal ran setzen und eine rudimentäre Erweiterung für ScITE schreiben, die beim Speichern von Dateien erkennt
- ob diese zu einem Repository gehören
- ob daran Änderungen vorgenommen wurden - und dieses dann anzeigen (Konsole oder Statuszeile)
- evtl. die git-Kommandos noch ins Kontextmenü packen
- .... mir fällt sicher noch mehr einSciTE4AutoIt listet unter den Tools auf "Update Source in Version Repository". Da wird aber "TortoiseGit" verwendet. Es gibt dort Unterschiede zu git, ist wohl so ein bischen wie AutoIt und AHK,
Also ich habe es deshalb auch noch nicht verwendet. -
Das Arbeiten mit der CMDLine geht doch mit AutoIt.
AutoIt
Alles anzeigenFunc _CMDLineRead($_sCMD) Local $PID = Run(@ComSpec & " /c " & $_sCMD, "", @SW_HIDE, $STDOUT_CHILD) Local $sLine, $sOutput = '' While 1 $sLine = StdoutRead($PID) If @error Then ExitLoop If StringStripWS($sLine, 8) <> '' Then $sOutput &= $sLine WEnd Return $sOutput EndFunc $group = _CMDLineRead("whoami /groups") ConsoleWrite($group & @CRLF)
Den Rückgabewert musst du natürlich noch auswerten.
-
Ich will mal noch einen Einzeiler in den Raum werfen...
AutoIt$sektion = StringRegExp(FileRead($pathINI), '(?m)\[([^\]]+)\]\r\n[^\r\n]+\r\nPersnr=' & $sPersNr, 1)[0] ConsoleWrite('+> Sektion: ' & $sektion & @CRLF)
Wobei hier zwingend ist, dass der Key "Persnr" der zweite Schlüssel unter dem Sektionsnamen ist. Anderenfalls muss für jede weiter Zeile vor "Persnr" eingefügt werden: [^\r\n]+\r\n
-
Manchmal komme ich mir vor, wie ein Schulanfänger. Nunja - Microsoft gibt sich ja auch viel Mühe, dass man sich so fühlt.
Allein die Namensgebung für die Funktionen in Excel sind zum Teil völlig von deren Wirkungsweise entkoppelt - ich vermute, dass einfach im Duden geblättert wurde und irgendwer bei Stop auf ein Wort zeigt. Bestes Bsp. - ich suchte eine Funktion, die einen Text in eine Zelladresse konvertiert. In meiner Einfalt habe ich vermutet "TextAlsAdresse" oder ähnlich. Da ich nichts fand, habe ich dann alle Funktionen quergelesen und bin fündig geworden bei "INDIREKT" !!
Also mit INDIREKT konnte ich, wenn auch recht umständlich, mein Problem lösen.
Ich habe ein Quelltabellenblatt, indem Daten erfasst werden, die relevanten Werte jeweils im Abstand von 53 Zeilen. Auf dem Zieltabellenblatt werden die Daten angezeigt im Abstand von 35 Zeilen. Ich möchte natürlich nur einmal den Zielbereich vorbereiten und dann im Block kopieren, wobei jeweils auf die korrekte nächste Zelle aus der Quelle zugegriffen wird. Ich hatte gehofft auf etwas in der Art: ReferenceShiftedRows(Quelle_Zelle, Shift, Ziel_Zelle, Shift).Zum besseren Verständnis habe ich mal eine Abbildung der Situation erstellt. Ich kann mir nicht vorstellen, dass diese Situation ungewöhnlich ist, also vielleicht gibt es ja doch schon eine Funktion dafür und ich hab sie nur nicht entdeckt. - Wenns jemand weiß, bitte melden.
-
Die Funktionen müssen bereits mit allen gewünschten Varianten ausgestattet sein. Du könntest dann über eine INI zur Laufzeit steuern, welche Teile der Funktion ausgeführt werden.