Hallo Leute,
ich habe gerade für ein Büro ein Skript geschrieben, das eine alte Excel-Funktion nachbildet. Es gibt die Funktion zwar auch in der aktuellsten Excel-Version, aber man muss schon suchen.. (ganz oben im Schnellstartbereich auf den Pfeil klicken->"Weitere Befehle..."->"Symbolleiste für den Schnellzugriff"->Combo von "Häufig verwendete Befehle" auf "Alle Befehle" ändern->"Maske...").
Also wirklich exotisch - aber vielleicht kann das irgendwer mal gebrauchen.
Die Funktion erstellt eine vertikale Maske aus Zeilen und Spalten, die man erst markieren muss. Die erste Spalte wird als Bezeichnung genommen und daneben sind Inputfelder mit den Inhalten der einzelnen Zellen eines Datensatzes. So kann man bei manueller Bearbeitung einen Excel-Datensatz mit vielen Spalten neben eine Programmoberfläche anzeigen und gut überschauen.
Die Funktion hat nun aber den Nachteil, dass nur max. 32 Spalten genutzt werden können. Das war mein Grund Hand anzulegen. Im gleichen Aufwisch habe ich dann auch noch Shortcuts eingebaut, um die Bearbeitung zu beschleunigen (- ich hoffe das besänftigt auch alle passionierten Automatisierer, denen bei diesem Projekt die Augen brennen ).
Im Anhang findet sich ein Skript und eine Beispieldatei. Die ist größer als die Dateien, um die es eigentlich geht. Da sieht man, dass nur eine bestimmte Anzahl Shortcuts vorgesehen sind. Das kann sich wer das mal braucht aber natürlich erweitern. Ladezeit ist hier auch etwas hoch. Aber wie gesagt, eigentlich geht es um kleinere Dateien.
Im Unterschied zur Originalfunktion muss man hier das Skript starten und dann die Datei auswählen. Auch markiert man hier nicht die Felder, sondern blendet alle Spalten/Zeilen aus, die man nicht sehen möchte, speichert und klickt dann auf den Button aktualisieren.
Spoiler anzeigen
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.15.0 (Beta)
Author: autoiter
Script Function:
"Erweiterte MS Excel Maske"
Excel-Maske nachbilden, mit erweiterten Funktionen.
Hotkeys:
- Strg + Pfeil oben = Nächster Datensatz
- Strg + Pfeil unten = Vorheriger Datensatz
- Alle Zellen im Datensatz über den den angegebenen Hotkey neben dem Zelleninhalt in der GUI.
#ce ----------------------------------------------------------------------------
#include <Array.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <FileConstants.au3>
#include <StructureConstants.au3>
#include <GUIScrollBars.au3>
#include <ScrollBarConstants.au3>
#include <Excel.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
Opt("GUICloseOnESC", 0)
OnAutoItExitRegister("_Exit")
#Region Deklarationen
Global $sPath_ExcelSource = FileOpenDialog("", @DesktopDir, "Excel-Dateien (*.xls;*.xlsx)", $FD_FILEMUSTEXIST) ; Den Startpfad anpassen..
If @error Then Exit
Global $aTaskbarPos = WinGetPos('[CLASS:Shell_TrayWnd]') ; Höhe der Taskbar für die richtige Positionierung der Fenster ermitteln.
If Not IsArray($aTaskbarPos) Then Exit MsgBox(0, '', 'Fehler beim Einrichten des Programms. Bitte neu starten.')
Global $hGUI, $iControls, $idNumber, $idBack, $idForward, $idReload, $aLabels[1], $aEdits[1], $aHotkeys[1], $idInputNumber, $idClipboardText
Global $iMaxSize, $iActData = 1, $aExcel, $sControl, $iEdit = 0, $iEditOld, $iActDataOld
Global $hGUIminWid = 375, $hGUIminHt = 725 ; Mindest- und Maximal-Größen für das Textfenster
Global $g_iHtit = _WinAPI_GetSystemMetrics($SM_CYCAPTION) ; -- siehe Hilfe etwa zu _WinAPI_CreateRoundRectRgn
Global $hInputWnd = WinGetHandle("[CLASS:SunAwtFrame]") ; Dieses Fenster sollte das Fenster sein, in das Daten eingetragen werden.
If @error Then $hInputWnd = "" ; Bei Hotkeys UP/DOWN wird dieses Fenster aktiviert, damit man gleich weiter arbeiten kann.
#EndRegion Deklarationen
#Region Excel-Objekt öffnen ; Einlesen (_ReadExcelToArray) wird in _CreateGUI gestartet.
Global $oExcel = _Excel_Open(True, Default, Default, True, True)
If @error Then Exit MsgBox(0, "", "Error creating the Excel application object. Excel UDF: @error = " & @error & ", @extended = " & @extended)
Global $oWorkbook = _Excel_BookOpen($oExcel, $sPath_ExcelSource, False, True)
If @error Then
$iError = @error
$iExtended = @extended
_Excel_Close($oExcel)
Exit MsgBox(0, "", "Error opening '" & $sPath_ExcelSource & "'. Excel UDF: @error = " & $iError & ", @extended = " & $iExtended)
EndIf
#EndRegion Excel-Objekt öffnen
#Region Setze Excel-Fensterposition
Global $hExcelWnd = WinGetHandle("[CLASS:XLMAIN]") ; Mit diesem Handle des Excel-Fensters wird nun weiter gearbeitet.
If @error Then Exit ConsoleWrite("Excel_Fenster_aktiv.png nicht gefunden" & @CRLF)
Global $sExcelText = WinGetTitle($hExcelWnd)
$hExcelWnd = WinGetHandle($sExcelText)
WinMove($sExcelText, "", 0, $aTaskbarPos[1] - 200, 1920, 200)
#EndRegion Setze Excel-Fensterposition
_CreateGUI() ; Programmoberfläche wird erstellt.
GUIRegisterMsg($WM_SIZE, "WM_SIZE") ; Fenstergröße ändern
GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") ; Fenstergröße Fixmaße
GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL") ; Vertikales Scrollen
GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL") ; Horizontales Scrollen
GUIRegisterMsg($WM_MOUSEWHEEL, "_WM_MOUSEWHEEL") ; Horizontales Scrollen mit Mausrad
GUICtrlSetState($aEdits[0], $GUI_FOCUS) ; markiere das erste Editfeld
HotKeySet("^{UP}", "_Hotkey") ; Hotkey für "Springe zum vorigen Datensatz"
HotKeySet("^{DOWN}", "_Hotkey") ; Hotkey für "Springe zum nächsten Datensatz"
GUISetState(@SW_SHOW, $hGUI)
While Sleep(10)
If Not WinExists($sExcelText) Then Exit ; Falls das Excel-Fenster manuell geschlossen wurde, beendet sich das Programm.
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $idInputNumber
$iPosition = GUICtrlRead($idInputNumber)
If $iPosition > $iMaxSize Then
GUICtrlSetData($idInputNumber, $iMaxSize)
$iPosition = $iMaxSize
ElseIf $iPosition = 0 Then
GUICtrlSetData($idInputNumber, 1)
$iPosition = 1
EndIf
_GoTo($iPosition)
Case $idBack
If $iActData > 1 Then
$iPosition = $iActData - 1
_GoTo($iPosition)
EndIf
Case $idForward
If $iActData < $iMaxSize Then
$iPosition = $iActData + 1
_GoTo($iPosition)
EndIf
Case $idReload
GUIDelete($hGUI)
For $i = 0 To $iControls - 1 ; die vergebenen Hotkeys werden deregistriert.
If $i < 9 Then
HotKeySet("^" & $i + 1)
ElseIf $i = 9 Then
HotKeySet("^0")
ElseIf $i > 9 And $i < 19 Then
HotKeySet("^{NUMPAD" & StringRight($i, 1) + 1 & "}")
ElseIf $i = 19 Then
HotKeySet("^{NUMPAD0}")
ElseIf $i > 19 And $i < 29 Then
HotKeySet("^+" & StringRight($i, 1) + 1)
ElseIf $i = 29 Then
HotKeySet("^+0")
ElseIf $i > 29 And $i < 39 Then
HotKeySet("^+{NUMPAD" & StringRight($i, 1) + 1 & "}")
ElseIf $i = 39 Then
HotKeySet("^+{NUMPAD0}")
ElseIf $i > 39 And $i < 49 Then
HotKeySet("^!" & StringRight($i, 1) + 1)
ElseIf $i = 49 Then
HotKeySet("^!0")
EndIf
Next
_CreateGUI()
GUISetState(@SW_SHOW, $hGUI)
EndSwitch
$sControl = ControlGetFocus($hGUI)
If $sControl <> "Edit1" And StringInStr($sControl, "Edit") Then
$iEdit = Number(StringTrimLeft($sControl, 4)) - 2 ; -2 weil Edit1 das für Direktsprünge ist und das jeweilige Control im Array in Position niedriger ist (0-basiert).
If $iEdit <> $iEditOld Or $iActData <> $iActDataOld Then ; Hier wird der markierte Editinhalt in die Zwischenablage geschoben.
GUICtrlSetData($idClipboardText, $aExcel[$iActData][$iEdit])
ClipPut($aExcel[$iActData][$iEdit])
$iEditOld = $iEdit
$iActDataOld = $iActData
EndIf
EndIf
WEnd
Func _Hotkey() ; Die Hotkey-Funktion, die bei allen Hotkeys aufgerufen wird.
;~ ConsoleWrite(@HotKeyPressed & @CRLF)
Switch @HotKeyPressed ; The last hotkey pressed.
Case "^{UP}"
If $iActData > 1 Then
$iPosition = $iActData - 1
_GoTo($iPosition)
Local $iExcelCellColor = $oExcel.Range("A" & $iPosition + 1).Interior.Color ; 16777215 = RGB Weiß // .Interior.Color für die Farbpallette.
If $iExcelCellColor = 16777215 Then
If $hInputWnd <> "" And WinExists($hInputWnd) Then WinActivate($hInputWnd)
EndIf
EndIf
Case "^{DOWN}"
If $iActData < $iMaxSize Then
$iPosition = $iActData + 1
_GoTo($iPosition)
Local $iExcelCellColor = $oExcel.Range("A" & $iPosition + 1).Interior.Color ; 16777215 = RGB Weiß // .Interior.Color für die Farbpallette.
If $iExcelCellColor = 16777215 Then
If $hInputWnd <> "" And WinExists($hInputWnd) Then WinActivate($hInputWnd)
EndIf
EndIf
Case Else
Local $iIndex = _ArraySearch($aHotkeys, @HotKeyPressed, 0, 0, 0, 0, 1, 1)
If $iIndex <> -1 Then
; Im folgenden wird der Inhalt der Zwischenablage zwischengespeichert.
; Dann der Inhalt der per Hoktey ausgewählten Zelle in die Zwischenablage gespeichert und anschließend per Tastaturbefehl Send("^v") geschrieben.
; Anschließend wird der verherige Inhalt wieder in die Zwischenablage gelegt.
; Das ist vllt. umständlicher Murks, aber das Send von Strings fehlten mal Zeichen. Daher diese Variante.
Local $sClip = ClipGet()
ClipPut($aExcel[$iActData][$iIndex])
Send("^v")
ClipPut($sClip)
EndIf
EndSwitch
EndFunc ;==>_Hotkey
Func _CreateGUI() ; Ich erstelle die GUI in einer Funktion. So geht es für mich am einfachsten mit dem Aktualisieren (neue GUI, wenn man Spalten ausgeblendet hat).
$aExcel = _ReadExcelToArray($sPath_ExcelSource, True)
If @error Then Exit ConsoleWrite($aExcel)
$iMaxSize = UBound($aExcel) - 1
$hGUI = GUICreate("", 500, @DesktopHeight - $aTaskbarPos[3] - $g_iHtit * 2, @DesktopWidth - 500 - 5, 0, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX), $GUI_WS_EX_PARENTDRAG)
$iControls = UBound($aExcel, 2)
$idInputNumber = GUICtrlCreateInput("" & $iMaxSize, 10, 7, 45, 20, BitOR($ES_RIGHT, $ES_NUMBER))
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$idNumber = GUICtrlCreateLabel("von " & $iMaxSize, 60, 10, 95, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$idClipboard = GUICtrlCreateLabel("In Zwischenablage:", 125, 5, 100, 15)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$idClipboardText = GUICtrlCreateLabel("", 225, 5, 235, 25)
GUICtrlSetFont(-1, 8.5, 600)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$idBack = GUICtrlCreateButton("Zurück", 10, 40, 140, 30)
GUICtrlSetResizing(-1, $GUI_DOCKHCENTER + $GUI_DOCKVCENTER + $GUI_DOCKTOP)
$idForward = GUICtrlCreateButton("Vorwärts", 150, 40, 140, 30)
GUICtrlSetResizing(-1, $GUI_DOCKHCENTER + $GUI_DOCKVCENTER + $GUI_DOCKTOP)
$idReload = GUICtrlCreateButton("Aktualisieren", 300, 40, 140, 30)
GUICtrlSetResizing(-1, $GUI_DOCKHCENTER + $GUI_DOCKVCENTER + $GUI_DOCKTOP)
Local $aAccelKeys[2][2] = [["{DOWN}", $idForward], ["{UP}", $idBack]]
GUISetAccelerators($aAccelKeys)
ReDim $aLabels[$iControls]
ReDim $aEdits[$iControls]
ReDim $aHotkeys[$iControls][2]
Local $iStartPosY = 100, $PosCorr = 0, $sHotkeytext = ""
For $i = 0 To $iControls - 1
$sHotkeytext = ""
If $i < 50 Then
If $i < 9 Then
$sHotkeytext = "CTRL+" & $i + 1
HotKeySet("^" & $i + 1, "_Hotkey")
$aHotkeys[$i][1] = "^" & $i + 1
ElseIf $i = 9 Then
$sHotkeytext = "CTRL+" & 0
HotKeySet("^0", "_Hotkey")
$aHotkeys[$i][1] = "^0"
ElseIf $i > 9 And $i < 19 Then
$sHotkeytext = "CTRL+N" & StringRight($i, 1) + 1
HotKeySet("^{NUMPAD" & StringRight($i, 1) + 1 & "}", "_Hotkey")
$aHotkeys[$i][1] = "^{NUMPAD" & StringRight($i, 1) + 1 & "}"
ElseIf $i = 19 Then
$sHotkeytext = "CTRL+N" & 0
HotKeySet("^{NUMPAD0}", "_Hotkey")
$aHotkeys[$i][1] = "!{NUMPAD0}"
ElseIf $i > 19 And $i < 29 Then
$sHotkeytext = "CTRL+SHIFT+" & StringRight($i, 1) + 1
HotKeySet("^+" & StringRight($i, 1) + 1, "_Hotkey")
$aHotkeys[$i][1] = "^+" & StringRight($i, 1) + 1
ElseIf $i = 29 Then
$sHotkeytext = "CTRL+SHIFT+" & 0
HotKeySet("^+0", "_Hotkey")
$aHotkeys[$i][1] = "^+0"
ElseIf $i > 29 And $i < 39 Then
$sHotkeytext = "CTRL+SHIFT+N" & StringRight($i, 1) + 1
HotKeySet("^+{NUMPAD" & StringRight($i, 1) + 1 & "}", "_Hotkey")
$aHotkeys[$i][1] = "^+{NUMPAD" & StringRight($i, 1) + 1 & "}"
ElseIf $i = 39 Then
$sHotkeytext = "CTRL+SHIFT+N" & 0
HotKeySet("^+{NUMPAD0}", "_Hotkey")
$aHotkeys[$i][1] = "^+{NUMPAD0}"
ElseIf $i > 39 And $i < 49 Then
$sHotkeytext = "CTRL+ALT+" & StringRight($i, 1) + 1
HotKeySet("^!" & StringRight($i, 1) + 1, "_Hotkey")
$aHotkeys[$i][1] = "^!" & StringRight($i, 1) + 1
ElseIf $i = 49 Then
$sHotkeytext = "CTRL+ALT+0"
HotKeySet("^!0", "_Hotkey")
$aHotkeys[$i][1] = "^!0"
EndIf
EndIf
$aLabels[$i] = GUICtrlCreateLabel($aExcel[0][$i], 5, $iStartPosY + $PosCorr + 2, 140, 20)
GUICtrlSetFont(-1, 11)
GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT + $GUI_DOCKVCENTER + $GUI_DOCKTOP)
$aEdits[$i] = GUICtrlCreateInput("", 150, $iStartPosY + $PosCorr, 230, 20)
GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT + $GUI_DOCKRIGHT + $GUI_DOCKVCENTER + $GUI_DOCKTOP)
$aHotkeys[$i][0] = GUICtrlCreateLabel($sHotkeytext, 390, $iStartPosY + $PosCorr, 90, 20)
GUICtrlSetFont(-1, 7.5)
GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT + $GUI_DOCKRIGHT + $GUI_DOCKVCENTER + $GUI_DOCKTOP)
$PosCorr += 25
Next
_GUIScrollBars_Init($hGUI, -1, $iControls + $iControls * 0.8) ; Scrollbars werden abhängig von der Anzahl der Controls initialisiert.
$iActData = 1
ControlSend($sExcelText, "", "", "^{HOME}") ; Springe in Excel-Liste zum ersten Datensatz.
For $i = 1 To $iMaxSize ; In dieser Schleife werden zum Start alle farbigen Felder überscrollt, weil sie in meinem Fall ignoriert werden sollen.
$iExcelCellColor = $oWorkbook.ActiveSheet.Range("A" & $i).Interior.Color ; Weiß = 16777215
If $iExcelCellColor = 16777215 Then
$iActData = $i
ExitLoop
Else
$iActData += 1
ControlSend($sExcelText, "", "", "{DOWN}")
EndIf
Next
GUICtrlSetData($idInputNumber, $iActData)
For $i = 0 To $iControls - 1
If $aExcel[$iActData][$i] = "" Then
If BitAND(GUICtrlGetState($aEdits[$i]), $GUI_SHOW) Then
GUICtrlSetState($aEdits[$i], $GUI_HIDE)
GUICtrlSetState($aHotkeys[$i][0], $GUI_HIDE)
EndIf
Else
If BitAND(GUICtrlGetState($aEdits[$i]), $GUI_HIDE) Then
GUICtrlSetState($aEdits[$i], $GUI_SHOW)
GUICtrlSetState($aHotkeys[$i][0], $GUI_SHOW)
EndIf
EndIf
If StringLen(Number($aExcel[$iActData][$i])) = 14 And (StringLeft($aExcel[$iActData][$i], 2) = "19" Or StringLeft($aExcel[$iActData][$i], 2) = "20") And StringRight($aExcel[$iActData][$i], 6) = "000000" Then
$aExcel[$iActData][$i] = StringFormat("%s.%s.%s", StringMid($aExcel[$iActData][$i], 7, 2), StringMid($aExcel[$iActData][$i], 5, 2), StringLeft($aExcel[$iActData][$i], 4)) ; 20170501000000 Datum fehleranfällig nach Logik umwandeln.
EndIf
GUICtrlSetData($aEdits[$i], $aExcel[$iActData][$i])
Next
EndFunc ;==>_CreateGUI
Func _GoTo($iPosition) ; Sprungfunktion in neue Datensätze. Wird von Zurück, Vorwärts und dem Direktsprung im Eingabe-Feld aufgerufen (Siehe While-Schleife).
Local $iBack = 0, $iDistance
If $iPosition - $iActData < 0 Then $iBack = 1 ; Evaluation, ob vorwärts oder rückwärts gesprungen werden soll.
$iActRow = $oExcel.ActiveCell.Row ; Wird noch einmal ermittelt, falls vorher manuell in der Excel Liste navigiert wurde.
$iExcelCellColor = $oExcel.Range("A" & $iPosition + 1).Interior.Color ; 16777215 = RGB Weiß // .Interior.Color für die Farbpallette.
If $iExcelCellColor <> 16777215 Then
GUICtrlSetState($idForward, $GUI_DISABLE)
WinActivate($sExcelText)
GUICtrlSetState($idForward, $GUI_ENABLE)
EndIf
If $iBack = 1 Then
$iDistance = $iPosition - $iActRow ; $iDistance ist die Anzahl der Sprünge. ($iPosition = Datensatz den die GUI anzeigt. $iActRow = aktive Zelle.
; -- Falls zwischenurch in der Excel-Liste gescrollt wurde (-die Excel-Liste soll ja immer mit scrollen)..
If $iDistance > 0 Then
For $i = 0 To $iDistance
ControlSend($sExcelText, "", "", "{DOWN}")
Next
Else
$iDistance = $iDistance * -1
For $i = 0 To $iDistance - 2
ControlSend($sExcelText, "", "", "{UP}")
Next
EndIf
$iActData = $iPosition
Else
$iDistance = $iPosition - $iActRow
If $iDistance < 0 Then
$iDistance = $iDistance * -1
For $i = 0 To $iDistance - 2
ControlSend($sExcelText, "", "", "{UP}")
Next
Else
For $i = 0 To $iDistance
ControlSend($sExcelText, "", "", "{DOWN}")
Next
EndIf
$iActData = $iPosition
EndIf
GUICtrlSetData($idInputNumber, $iActData)
For $i = 0 To $iControls - 1
If $aExcel[$iActData][$i] = "" Then
If BitAND(GUICtrlGetState($aEdits[$i]), $GUI_SHOW) Then
GUICtrlSetState($aEdits[$i], $GUI_HIDE)
GUICtrlSetState($aHotkeys[$i][0], $GUI_HIDE)
EndIf
Else
If BitAND(GUICtrlGetState($aEdits[$i]), $GUI_HIDE) Then
GUICtrlSetState($aEdits[$i], $GUI_SHOW)
GUICtrlSetState($aHotkeys[$i][0], $GUI_SHOW)
EndIf
EndIf
If StringLen(Number($aExcel[$iActData][$i])) = 14 And (StringLeft($aExcel[$iActData][$i], 2) = "19" Or StringLeft($aExcel[$iActData][$i], 2) = "20") And StringRight($aExcel[$iActData][$i], 6) = "000000" Then
$aExcel[$iActData][$i] = StringFormat("%s.%s.%s", StringMid($aExcel[$iActData][$i], 7, 2), StringMid($aExcel[$iActData][$i], 5, 2), StringLeft($aExcel[$iActData][$i], 4)) ; 20170501000000 Datum fehleranfällig nach Logik umwandeln.
EndIf
GUICtrlSetData($aEdits[$i], $aExcel[$iActData][$i])
Next
GUICtrlSetState($aEdits[$iEdit], $GUI_FOCUS)
EndFunc ;==>_GoTo
#Region Scrollbars
Func _WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) ; zum Hoch- und Runter-scrollen in der GUI mit Scrollbars
Local $iPos = _GUIScrollBars_GetScrollPos($hWnd, $SB_VERT)
_GUIScrollBars_SetScrollInfoPos($hGUI, $SB_VERT, $iPos - (BitShift($wParam, 16) / 120))
Return $GUI_RUNDEFMSG
EndFunc ;==>_WM_MOUSEWHEEL
Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) ; Mit kleiner Änderung aus der Hilfe zu _GUIScrollBars_Init kopiert.
_GUIScrollBars_SetScrollInfoPos($hGUI, $SB_VERT, 0) ; Sonst gab es den Effekt, wenn man nicht ganz oben war und die GUI-Breite geändert hat, die Controls nicht mehr alle sichtbar waren.
#forceref $iMsg, $wParam
Local $iIndex = -1, $iCharY, $iCharX, $iClientMaxX, $iClientX, $iClientY, $iMax
For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
$iIndex = $x
$iClientMaxX = $__g_aSB_WindowInfo[$iIndex][1]
$iCharX = $__g_aSB_WindowInfo[$iIndex][2]
$iCharY = $__g_aSB_WindowInfo[$iIndex][3]
$iMax = $__g_aSB_WindowInfo[$iIndex][7]
ExitLoop
EndIf
Next
If $iIndex = -1 Then Return 0
Local $tSCROLLINFO = DllStructCreate($tagSCROLLINFO)
; Retrieve the dimensions of the client area.
$iClientX = BitAND($lParam, 0x0000FFFF)
$iClientY = BitShift($lParam, 16)
$__g_aSB_WindowInfo[$iIndex][4] = $iClientX
$__g_aSB_WindowInfo[$iIndex][5] = $iClientY
; Set the vertical scrolling range and page size
DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE))
DllStructSetData($tSCROLLINFO, "nMin", 0)
DllStructSetData($tSCROLLINFO, "nMax", $iMax)
DllStructSetData($tSCROLLINFO, "nPage", $iClientY / $iCharY)
_GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
; Set the horizontal scrolling range and page size
DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE))
DllStructSetData($tSCROLLINFO, "nMin", 0)
DllStructSetData($tSCROLLINFO, "nMax", 2 + $iClientMaxX / $iCharX)
DllStructSetData($tSCROLLINFO, "nPage", $iClientX / $iCharX)
_GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_SIZE
Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam) ; Aus der Hilfe zu _GUIScrollBars_Init kopiert.
#forceref $iMsg, $lParam
Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
Local $iIndex = -1, $iCharX, $iPosX
Local $iMin, $iMax, $iPage, $iPos, $iTrackPos
For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
$iIndex = $x
$iCharX = $__g_aSB_WindowInfo[$iIndex][2]
ExitLoop
EndIf
Next
If $iIndex = -1 Then Return 0
; ; Get all the horizontal scroll bar information
Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
$iMin = DllStructGetData($tSCROLLINFO, "nMin")
$iMax = DllStructGetData($tSCROLLINFO, "nMax")
$iPage = DllStructGetData($tSCROLLINFO, "nPage")
; Save the position for comparison later on
$iPosX = DllStructGetData($tSCROLLINFO, "nPos")
$iPos = $iPosX
$iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
#forceref $iMin, $iMax
Switch $iScrollCode
Case $SB_LINELEFT ; user clicked left arrow
DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)
Case $SB_LINERIGHT ; user clicked right arrow
DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)
Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)
Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)
Case $SB_THUMBTRACK ; user dragged the scroll box
DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
EndSwitch
; // Set the position and then retrieve it. Due to adjustments
; // by Windows it may not be the same as the value set.
DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
_GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
_GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
;// If the position has changed, scroll the window and update it
$iPos = DllStructGetData($tSCROLLINFO, "nPos")
If ($iPos <> $iPosX) Then _GUIScrollBars_ScrollWindow($hWnd, $iCharX * ($iPosX - $iPos), 0)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_HSCROLL
Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam) ; Aus der Hilfe zu _GUIScrollBars_Init kopiert.
#forceref $iMsg, $wParam, $lParam
Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
Local $iIndex = -1, $iCharY, $iPosY
Local $iMin, $iMax, $iPage, $iPos, $iTrackPos
For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
$iIndex = $x
$iCharY = $__g_aSB_WindowInfo[$iIndex][3]
ExitLoop
EndIf
Next
If $iIndex = -1 Then Return 0
; Get all the vertial scroll bar information
Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
$iMin = DllStructGetData($tSCROLLINFO, "nMin")
$iMax = DllStructGetData($tSCROLLINFO, "nMax")
$iPage = DllStructGetData($tSCROLLINFO, "nPage")
; Save the position for comparison later on
$iPosY = DllStructGetData($tSCROLLINFO, "nPos")
$iPos = $iPosY
$iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
Switch $iScrollCode
Case $SB_TOP ; user clicked the HOME keyboard key
DllStructSetData($tSCROLLINFO, "nPos", $iMin)
Case $SB_BOTTOM ; user clicked the END keyboard key
DllStructSetData($tSCROLLINFO, "nPos", $iMax)
Case $SB_LINEUP ; user clicked the top arrow
DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)
Case $SB_LINEDOWN ; user clicked the bottom arrow
DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)
Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)
Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)
Case $SB_THUMBTRACK ; user dragged the scroll box
DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
EndSwitch
; // Set the position and then retrieve it. Due to adjustments
; // by Windows it may not be the same as the value set.
DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
_GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
_GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
;// If the position has changed, scroll the window and update it
$iPos = DllStructGetData($tSCROLLINFO, "nPos")
If ($iPos <> $iPosY) Then
_GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
$iPosY = $iPos
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_VSCROLL
#EndRegion Scrollbars
Func _WM_GETMINMAXINFO($hWnd, $Msg, $wParam, $lParam) ; Mindestgrößen der GUI
$tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
DllStructSetData($tagMaxinfo, 7, $hGUIminWid) ; min X
DllStructSetData($tagMaxinfo, 8, $hGUIminHt) ; min Y
Return 0
EndFunc ;==>_WM_GETMINMAXINFO
Func _Exit() ; Aufräumen beim Beenden
If IsObj($oExcel) Then _Excel_Close($oExcel)
EndFunc ;==>_Exit
Func _ReadExcelToArray($sPath_ExcelSource, $bOnlyVisibleCols = False, $bOnlyVisibleRows = True) ; Funktion zum Einlesen der Excel-Datei. Wird im Programm so aufgerufen, dass nur sichtbare Spalte und Zeilen ausgelesen werden.
If Not FileExists($sPath_ExcelSource) Then Return SetError(1, 0, "Error: File not found!")
If $bOnlyVisibleCols = Default Then $bOnlyVisibleCols = False
Local $iError, $iExtended
With $oWorkbook.ActiveSheet ; Aus dem Wiki. Ermittelt den Bereich von A1 bis zur letzten benutzten Zelle. https://www.autoitscript.com/wiki/Excel_Range#Last_Cell
$oRangeLast = .UsedRange.SpecialCells($xlCellTypeLastCell)
$oRange = .Range(.Cells(1, 1), .Cells($oRangeLast.Row, $oRangeLast.Column))
EndWith
Local $aArray = _Excel_RangeRead($oWorkbook, Default, $oRange)
If @error Then
$iError = @error
$iExtended = @extended
_Excel_Close($oExcel)
Return SetError(4, 0, "Error reading from workbook. Excel UDF: @error = " & $iError & ", @extended = " & $iExtended)
EndIf
If $bOnlyVisibleCols Then ; Wenn im Array nur sichtbare Spalten enthalten sein sollen.
Local $aColumnsLetters = __Excel_Read_Write_ColumnsLetters()
For $i = UBound($aArray, 2) - 1 To 0 Step -1
If ($oWorkbook.ActiveSheet.Range($aColumnsLetters[$i] & 1).EntireColumn.Hidden) Then _ArrayColDelete($aArray, $i)
Next
EndIf
If $bOnlyVisibleRows Then ; Wenn im Array nur sichtbare Zeilen enthalten sein sollen.
For $i = UBound($aArray) - 1 To 1 Step -1
If ($oWorkbook.ActiveSheet.Range("A" & $i).EntireRow.Hidden) Then _ArrayDelete($aArray, $i - 1)
Next
EndIf
Return $aArray
EndFunc ;==>_ReadExcelToArray
#Region __Excel_Read_Write_ColumnsLetters ; aus meiner UDF zur Excel-UDF :D
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __Excel_Read_Write_ColumnsLetters
; Description ...: Erstellt ein Array mit Buchstaben von A bis ZZ (702 Elemente)
; Syntax.........: __Excel_Read_Write_ColumnsLetters ( )
; ===============================================================================================================================
Func __Excel_Read_Write_ColumnsLetters() ; In dieser Funktion wird ein Array mit Buchstaben für die Excel-Spalten in der ListGUI gebildet.
Local $aCols[702] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", _
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", _
"X", "Y", "Z"]
Local $iColNumber = 26
For $i = 0 To 25
For $ii = 0 To 25
$aCols[$iColNumber] = $aCols[$i] & $aCols[$ii]
$iColNumber += 1
Next
Next
Return $aCols
EndFunc ;==>__Excel_Read_Write_ColumnsLetters
#EndRegion __Excel_Read_Write_ColumnsLetters
Alles anzeigen