Malicious Office (OOXML) / .DOCX — malware analysis report

Static analysis result for SHA-256 7ecb5894b0df20f2…

MALICIOUS

Office (OOXML) / .DOCX

1.62 MB Created: 2025-12-01 09:18:00 UTC Authoring application: Microsoft Office Word 16.0000 First seen: 2026-06-15
MD5: aaaf4066c6b97e27bf20b03dd9d1529f SHA-1: 22b09c5eac98ba36261618a21916d1972dd558e5 SHA-256: 7ecb5894b0df20f2a1c63c4d2edc7f3d7b2453ab613fa89cb79d360b16779e9c
978 Risk Score

Heuristics 21

  • ClamAV: Doc.Downloader.Pwshell-10001336-0 critical CLAMAV_DETECTION
    ClamAV detected this file as malware: Doc.Downloader.Pwshell-10001336-0
  • VBA project inside OOXML medium 17 related findings OOXML_VBA
    Document contains a VBA project — VBA macros present
  • Potential Shell call in VBA critical OLE_VBA_SHELL
    Potential Shell call in VBA
    Matched line in script
      shell "cmd /c start https://zifra-plus.ru/support", vbHide
  • WScript.Shell usage critical OLE_VBA_WSCRIPT
    WScript.Shell usage
    Matched line in script
        Set shell = CreateObject("WScript.Shell")
  • PowerShell reference in VBA critical OLE_VBA_PS
    PowerShell reference in VBA
    Matched line in script
        command = "powershell.exe -ExecutionPolicy Bypass -Command """ & psCode & """"
  • URLDownloadToFile in VBA critical OLE_VBA_DOWNLOAD
    URLDownloadToFile in VBA
    Matched line in script
    Function URLDownloadToFile_Yandex(ByVal url, Optional ByVal Файл на локальной машине)
  • LOLBin reference in VBA critical OLE_VBA_LOLBIN
    LOLBin reference in VBA
    Matched line in script
            objShell.ShellExecute "wscript.exe", ПутьRepairEquation, "", "runas", 0
  • VBA stages a PowerShell/LOLBin download-and-run command critical OLE_VBA_BITSTRANSFER_DROPPER
    The macro assembles a download command using a PowerShell or LOLBin download primitive (Start-BitsTransfer, Invoke-WebRequest, Net.WebClient, bitsadmin, certutil, ...) that fetches a remote payload, then executes it -- writing it to a script file and running it, or launching it directly from an auto-exec handler. The keywords are commonly split with PowerShell backtick / cmd caret escapes to evade scanners; this detection de-escapes the source first. A high-confidence downloader/dropper, stronger than the individual Shell / download keywords on their own.
    Matched line in script
    Private Sub Document_New()
  • VBA property-stored shellcode loader critical OLE_VBA_PROPERTY_SHELLCODE_LOADER
    VBA auto-exec macro takes the address (VarPtr) of a byte buffer decoded from a document property, marks memory executable (VirtualProtect/VirtualAlloc), and transfers control through a callback API (e.g. SetTimer/EnumWindows). The payload is hidden in the document properties rather than the macro source — the SVCReady loader pattern, a native shellcode runner rather than a parser CVE.
    Matched line in script
      Public Declare PtrSafe Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
  • VBA downloads and writes a file to disk critical OLE_VBA_HTTP_DROP_EXEC
    VBA reads an HTTP response body and writes it to disk (ADODB.Stream SaveToFile). Combined with the auto-exec/Shell paths this is a download-drop dropper even when the COM ProgIDs are built dynamically to evade keyword scanning.
    Matched line in script
            oStream.Write WinHttpReq.responseBody
  • VBA macro-virus self-replication / AV tampering critical OLE_VBA_MACRO_VIRUS_REPLICATION
    VBA macro programmatically rewrites VBA project code through the VBE object model (CodeModule/VBComponents InsertLines/DeleteLines/AddFromString or OrganizerCopy) to copy itself into the global template and other open documents, and/or disables Office macro-virus protection (Options.VirusProtection = False). This is the defining behavior of the W97M document macro-virus family — self-replicating code with no benign document use, independent of any AV signature.
    Matched line in script
          Application.OrganizerCopy Source:=ПутьИмяШаблона, _
  • VBA email-worm self-replication (Outlook mass-mailer) critical OLE_VBA_EMAIL_WORM_SELF_REPLICATION
    VBA macro drives Outlook to mass-mail itself: it automates Outlook.Application, programmatically creates a mail item, and spreads by attaches a file to the outgoing message, sends the message programmatically. Harvesting recipients from the address book / inbox and auto-attaching the carrier to outgoing messages is the defining behavior of the Melissa / LoveLetter / W97M mass-mailer worm lineage — there is no benign document use, independent of any AV signature.
    Matched line in script
        Set olMailItem = olApp.CreateItem(0)
  • CreateObject call high OLE_VBA_CREATEOBJ
    CreateObject call
    Matched line in script
        Set ExcelТек2 = CreateObject("Excel.Application").Workbooks.Add.Sheets(1)
  • GetObject call high OLE_VBA_GETOBJ
    GetObject call
    Matched line in script
                Set ExcelФайл = GetObject(Class:="Excel.Application")
  • cmd.exe reference in VBA high OLE_VBA_CMD
    cmd.exe reference in VBA
    Matched line in script
      shell "cmd /c start https://zifra-plus.ru/support", vbHide
  • VBA polls global keyboard state (keylogger) high OLE_VBA_KEYLOGGER_SPYWARE
    The macro declares or calls a Win32 keystroke-monitoring API (GetAsyncKeyState, SetWindowsHookEx WH_KEYBOARD, or GetKeyboardState) to capture keystrokes system-wide. No legitimate document automation polls global key state; this is the core of a VBA keylogger, usually paired with active-window capture (GetForegroundWindow) and a log file. A high-confidence spyware behaviour independent of any download / Shell evidence.
    Matched line in script
    Private Declare PtrSafe Function GetAsyncKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
  • VBA p-code auto-exec with execution tokens high OLE_VBA_PCODE_AUTOEXEC_EXEC
    Triggers on the COMBINATION of two tokens co-occurring in the same compiled VBA/cache stream: an auto-execution entry point (Auto_Open / AutoOpen / Document_Open / Workbook_Open / Auto_Close / AutoClose) AND a shell/download/object-execution token (Shell, CreateObject, GetObject, PowerShell, cmd.exe, URLDownloadToFile, WinHttp, XMLHTTP, ADODB.Stream, ShellExecute, ExecuteExcel4Macro). Neither token alone fires it — it is the pairing that flags p-code-only or source-extraction-failure macro documents where the visible VBA source is unavailable. The matched tokens are named in the detail line below.
  • Document_Open macro low OLE_VBA_DOCOPEN
    Document_Open macro
    Matched line in script
    Private Sub Document_Open()
  • Environ() call (env variable access) low OLE_VBA_ENVIRON
    Environ() call (env variable access)
    Matched line in script
          ProgFiles = Environ("PROGRAMFILES")
  • Suspicious extracted artifact medium EXTRACTED_FILE_STATIC_TRIAGE
    One 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_URL
    One 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 https://zifra-plus.ru/support Referenced by macro
    • http://zifra-plus.ruReferenced by macro
    • https://zifra-plus.ru/wp-content/uploads/dae-uploads/Referenced by macro
    • https://zifra-plus.ru/Referenced by macro
    • https://edu-plus.ru/ass_logs.php?&action=Referenced by macro
    • http://am.rusimport.ru/MSAccess/topic.aspx?ID=585Referenced by macro
    • https://zifra-plus.ru/downloads/updateserver.txtReferenced by macro
    • https://zifra-plus.ru/downloads/jupiter/Referenced by macro
    • https://zifra-plus.ru/downloads/jupiter/modules/Referenced by macro
    • https://zifra-plus.ru/product/ass-premiumReferenced by macro
    • https://zifra-plus.ru/get_license_id.phpReferenced by macro
    • https://zifra-plus.ru/get_license_activations.phpReferenced by macro
    • https://zifra-plus.ru/save_license_activation.phpReferenced by macro
    • https://portal.edu-plus.ru/grade/report/overview/index.php?id=266Referenced by macro
    • https://edu-plus.ruReferenced by macro
    • http://schemas.microsoft.com/office/word/2010/wordprocessingCanvasReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2014/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2015/9/8/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2015/10/21/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/5/9/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/5/10/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/5/11/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/5/12/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/5/13/chartexReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/5/14/chartexReferenced by macro
    • http://schemas.openxmlformats.org/markup-compatibility/2006Referenced by macro
    • http://schemas.microsoft.com/office/drawing/2016/inkReferenced by macro
    • http://schemas.microsoft.com/office/drawing/2017/model3dReferenced by macro
    • http://schemas.microsoft.com/office/2019/extlstReferenced by macro
    • http://schemas.openxmlformats.org/officeDocument/2006/relationshipsReferenced by macro
    • http://schemas.openxmlformats.org/officeDocument/2006/mathReferenced by macro
    • http://schemas.microsoft.com/office/word/2010/wordprocessingDrawingReferenced by macro
    • http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawingReferenced by macro
    • http://schemas.openxmlformats.org/wordprocessingml/2006/mainReferenced by macro
    • http://schemas.microsoft.com/office/word/2010/wordmlReferenced by macro
    • http://schemas.microsoft.com/office/word/2012/wordmlReferenced by macro
    • http://schemas.microsoft.com/office/word/2018/wordml/cexReferenced by macro
    • http://schemas.microsoft.com/office/word/2016/wordml/cidReferenced by macro
    • http://schemas.microsoft.com/office/word/2018/wordmlReferenced by macro
    • http://schemas.microsoft.com/office/word/2023/wordml/word16duReferenced by macro
    • http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahashReferenced by macro
    • http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlockReferenced by macro
    • http://schemas.microsoft.com/office/word/2015/wordml/symexReferenced by macro
    • http://schemas.microsoft.com/office/word/2010/wordprocessingGroupReferenced by macro
    • http://schemas.microsoft.com/office/word/2010/wordprocessingInkReferenced by macro
    • http://schemas.microsoft.com/office/word/2006/wordmlReferenced by macro
    • http://schemas.microsoft.com/office/word/2010/wordprocessingShapeReferenced by macro
    • https://dzen.ru/a/ZeHdINfW3DCYfHfHReferenced by macro
    • https://www.microsoft.com/en-us/download/Confirmation.aspx?ID=13255Referenced by macro
    • https://vh458.timeweb.ru/pma/index.php?route=/sql&db=cl11741_omidpo&table=wp_ass_logs_structure&pos=0Referenced by macro
    +8 more URL(s)

Extracted artifacts 2

Files carved from inside the sample during analysis.

FilenameKindSourceSize
macros.bas🔏 SignedVBA project digital signature
Covers VBA source only — not the compiled p-code. A digital signature does not by itself mean the macro is safe.
vba-macro oletools.olevba.extract_macros (decoded VBA source from OOXML) 1164863 bytes
SHA-256: ae090be33b6fcf534cb5689d4848ebe8b5f634b4d00dd7de71d6a6ef7bad9fae
Preview script
First 1,000 lines of the extracted script
Attribute VB_Name = "ThisDocument"
Attribute VB_Base = "0{00020906-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

Private Sub Document_Close()
  On Error Resume Next
  ЗакрытьExcel
  СохранитьНакоплСтат
End Sub

Private Sub Document_New()
  On Error Resume Next
  АвтоВыделПоля
  ЗакрытьExcel
End Sub

Private Sub Document_Open()
  On Error Resume Next
  Опции_2 = ЗагрСвойство(ActiveDocument, "Опции")
  If Опции_2 <> "" Then Опции_(ПолучитьНомерДокумента) = ЗагрСвойство(ActiveDocument, "Опции")
  АвтоВыделПоля
  ЗакрытьExcel
End Sub



Attribute VB_Name = "Мастер шаблонов"
'--------------------------------------------------------------------------
'ФУНКЦИИ ДЛЯ ГЕНЕРАЦИИ ДОКУМЕНТОВ И РАССЫЛОК (1.00)
'--------------------------------------------------------------------------
Public ОткрытыеДокументы(100) As String
Public Опции_(100), Excel, НеЗакрыватьExcelПриВыходе, Email, ПозЛога, СущВремФайлСод, СущВремФайлИмя, ОшибкаSQL, ТестGIFT, ФлагЗапуска, ТекущДокумент, ОбрабатываемыйДокумент, НажатаКлавишаОтмены
Public ExcelТек
Public ExcelТек2
Public Позиция As Long, ФормулаДо, ПервыйЗапуск As Boolean, ПослЭлемент As Boolean, РежимОчистки, ПослСохрФайл
Public KoefStr 'Коэффициент заполнения строк (через сколько строк выгружать данные)
Function ПолучитьНомерДокумента()
  On Error Resume Next
  If Not (IsObject(ТекущДокумент) And Not ТекущДокумент Is Nothing) Then
    Set ОбрабатываемыйДокумент = ActiveDocument
  Else
    Set ОбрабатываемыйДокумент = ТекущДокумент
  End If
  
  For i = 1 To UBound(ОткрытыеДокументы)
    If ОткрытыеДокументы(i) = DocumentFullName(ОбрабатываемыйДокумент) Then
      ПолучитьНомерДокумента = i
      Exit Function
    End If
  Next i
  For i = 1 To UBound(ОткрытыеДокументы)
    If ОткрытыеДокументы(i) = "" Then
      ОткрытыеДокументы(i) = DocumentFullName(ОбрабатываемыйДокумент)
      ПолучитьНомерДокумента = i
      Exit Function
    End If
  Next i
End Function
Sub ОткрытьРедакторПолей_(Optional ByVal control As IRibbonControl)
  If Not ПроверкаДокумента Then Exit Sub
  Set Выделение = Selection.Range
  ДобЗаписьСтатистИспольз 80
  On Error Resume Next
  РежимОчистки = False
  
  If НажатаКлавиша(16) Then РежимОчистки = 1 'SHIFT
  If НажатаКлавиша(17) Then РежимОчистки = 2 'CTRL
  If НажатаКлавиша(18) Then РежимОчистки = 3 'ALT
  
  РедакторПолей.Show
  Выделение.Select
End Sub
Sub Настройки_(Optional ByVal control As IRibbonControl)
  If Not ПроверкаДокумента Then Exit Sub
  ДобЗаписьСтатистИспольз 81
  НастройкиПрограммы.Show
End Sub
Sub ОткрытьПутьСохранения(Optional ByVal control As IRibbonControl)
  If Not ПроверкаДокумента Then Exit Sub
  ПолучитьНомерДокумента
  Опции_(ПолучитьНомерДокумента) = ЗагрСвойство(ОбрабатываемыйДокумент, "Опции")
  
  ДобЗаписьСтатистИспольз 82
  РежимПечати = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "РежимПечати"))
  If Not РежимПечати Then Exit Sub
  
  ПутьСохранения = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПутьСохранения")
  ПутьСохранения = ЗаменаКонстант(ПутьСохранения)

  If Файлы_ВыделитьПуть(ПреобрНазвПолей(ПутьСохранения)) <> "" Then ПутьСохранения = Файлы_ВыделитьПуть(ПреобрНазвПолей(ПутьСохранения))
  ПутьСохранения = Файлы_ПутьАбсол(ПреобрНазвПолей(ПутьСохранения), ОбрабатываемыйДокументPath)
  
  If Not ПутьСуществует(ПутьСохранения) Then ПутьСохранения = Файлы_ВыделитьПуть(ПутьСохранения)
  If Not ПутьСуществует(ПутьСохранения) Then ПутьСохранения = Файлы_ВыделитьПуть(ПутьСохранения)
  
  If Файлы_ПутьСущ(ПутьСохранения) And Len(ПутьСохранения) > 2 Then
    If ПослСохрФайл <> "" Then
      Пров_Выделить ПослСохрФайл
    Else
      Пров_Открыть ПутьСохранения
    End If
  ElseIf Len(ПутьСохранения) = 1 Then
    MsgBox "В параметрах не задан путь для сохранения результатов", vbExclamation
  Else
    MsgBox "Не существует путь " & ПутьСохранения, vbExclamation
  End If
End Sub
Sub Запуск_Клав()
  Запуск_
End Sub
Sub ОбработкаФлагаЗапуска()
  If ФлагЗапуска = 1 Then ФлагЗапуска = 2
End Sub
Sub Запуск_(Optional ByVal control As IRibbonControl, Optional ВыводитьСообщение, Optional ПринудительноПоОдному, Optional ОпцияРаботы As ОпцияРаботыМастераШаблонов = ОпцияРаботыМастераШаблоновСтандартная)
  If Not ПроверкаДокумента Then Exit Sub
  ДобЗаписьСтатистИспольз 83
  РежимГенерации = False
  If IsMissing(ВыводитьСообщение) And IsMissing(ПринудительноПоОдному) Then
    'Нажата кнопка запуск, установка флага запуска в первоначальное положение
    ФлагЗапуска = 1
    РежимГенерации = True
  End If
  
  If IsMissing(ВыводитьСообщение) Then ВыводитьСообщение = True
  If IsMissing(ПринудительноПоОдному) Then ПринудительноПоОдному = False
  
  If ВыводитьСообщение Then If MsgBox("Запустить генерацию?", vbYesNo + vbQuestion) = vbNo Then Exit Sub
  If Not ОткрытьExcel Then Exit Sub
  
  System.Cursor = wdCursorWait
  НачВремя = Timer
  ПоОдному = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПоОдному"))
  If ПринудительноПоОдному Then ПоОдному = True
  If ПоОдному And Позиция = 0 And Not РежимГенерации Then
    ПерейтиКзаписи_
    ОбработкаФлагаЗапуска
    Exit Sub
  End If
  
#If VBA7 Then
  Application.UndoRecord.StartCustomRecord ("Запуск обработки")
#End If
  
  ПоказСкрытогоТекста = ActiveWindow.View.ShowHiddenText
  'ActiveWindow.View.ShowHiddenText = True
  
  НачСтр = ПолучНачСтр
  ПечатьНастрПечСписок = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьНастрПечСписок"))
  ПечатьПоследВсеСтр = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьПоследВсеСтр"))
  РежимПечати = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "РежимПечати"))
  ПечатьPDF = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьPDF"))
  ПечатьDOCX = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьDOCX"))
  ПечатьDOCX_ускор = CBool(IIf(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьDOCX_ускор") = "", 0, Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьDOCX_ускор") = ""))
  НазваниеШаблона = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "НазваниеШаблона")
  КонСтрока = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "КонСтрока"))
  КонСтрокаЗнач = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "КонСтрокаЗнач")
  ОтпрEmail = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ОтпрEmail"))
  SMTPсервер = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "SMTPсервер")
  SMTPпорт = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "SMTPпорт")
  SMTPлогин = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "SMTPлогин")
  SMTPпароль = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "SMTPпароль")
  Шаблон = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "Шаблон")
  Шаблон2 = Шаблон
  ТемаСообщ = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ТемаСообщ")
  ИмяОтпр = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ИмяОтпр")
  Уведомления = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "Уведомления"))
  КопияСообщ = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "КопияСообщ"))
  АдресКопииСообщения = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "АдресКопииСообщения")
  ТолькоАдресКопии = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ТолькоАдресКопии"))
  ОкноЛога = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ОкноЛога"))
  ПечатьDOCX_ускор = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьDOCX_ускор"))
  
  отдельные = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "отдельные"))
  один = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "один"))
  
  ОткрытьПосле = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ОткрытьПосле"))
  Распечатать = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "Распечатать"))
  ПечатьPDF_принтер = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьPDF_принтер")) 'печатать после формирования PDF
  КопирСообщБуфер = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "КопирСообщБуфер"))
  
  ОчищатьПапку = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ОчищатьПапку"))
  
  КолВо = 0
  
  If ПоОдному Then
    Сдвиг = 0
    МаксПоз = 1
    'ЗапускОднойСтроки Сдвиг
  Else
    'Определение объема печати
    Сдвиг = 1
    МаксПоз = 0
    For z = 1 To UBound(Excel)
      If Not IsEmpty(Excel(z)) Then
        КонСтр = Excel(z).cells(65535, 1).End(-4162).row
      Else
        КонСтр = -1
      End If
      For i = НачСтр To КонСтр
        If КонСтрока Then If КонСтрокаЗнач - НачСтр + 1 = МаксПоз Then GoTo Выход
        МаксПоз = МаксПоз + 1
      Next i
    Next z
Выход:
    Позиция = Empty
  End If

  If НажатаКлавишаОтмены Then
    DoEvents
    GoTo Завершение
  End If
  
  If РежимГенерации Then
    Индик_Сброс Индикатор_2.Индик, 1, МаксПоз, "Формирование (ESC - Отмена) ..."
  End If
  
  Dim doc As Document
  Dim СущФайл As Document
  
  Dim ТекущийДокумент As Document
  Set ТекущийДокумент = ОбрабатываемыйДокумент
  
  If ПечатьDOCX_ускор Then
    ОбрабатываемыйДокумент.Save
    ВремФайл = Файлы_ПутьTemp & "\" & ОбрабатываемыйДокумент.Name
    Файлы_КопирФайл ОбрабатываемыйДокументPath & "\" & ОбрабатываемыйДокумент.Name, ВремФайл
    Сжатие_Распаковать7z ВремФайл, Файлы_ПутьTemp & "\Assistent\Temp", ThisDocumentPath & "\Ass_Addons"
    'Пров_Выделить ВремФайл
    DocumentXML = Файлы_ОткрытьФайл(Файлы_ПутьTemp & "\Assistent\Temp\word\document.xml", win)
  End If
  
  If Not ПринудительноПоОдному And ОкноЛога And ОтпрEmail Then ОчиститьЛог
  For i = 1 To IIf(МаксПоз = 0, 1, МаксПоз)
    DoEvents
    System.Cursor = wdCursorWait
    If (РежимПечати And ((ПечатьDOCX And отдельные) Or (ПечатьPDF And отдельные) Or ((ПечатьDOCX Or ПечатьPDF) And один))) Or ОтпрEmail Then
      If ОпцияРаботы = ОпцияРаботыМастераШаблоновСтандартная Then ЗапускОднойСтроки Сдвиг
      If i = 1 Then
        'ОткрытьРедакторПолей_
        'Unload РедакторПолей
      End If
    Else
      If ОпцияРаботы = ОпцияРаботыМастераШаблоновСтандартная Then
        If Not ПоОдному Then ЗапускОднойСтроки Сдвиг
      End If
    End If
    If НажатаКлавишаОтмены Then
      GoTo Выход
    End If
        
    ПечатьНастрПечСписок = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьНастрПечСписок"))
    ПечатьПоследВсеСтр = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПечатьПоследВсеСтр"))
    
    If РежимПечати Or Not РежимПечати Then
      If Not (ПечатьPDF Or ПечатьDOCX) And Not ОтпрEmail Then
        ПечатьДокументаСнастройками
      Else
        If отдельные Then
          ИмяФайла = ПреобрНазвПолей(НазваниеШаблона)
        Else
          ИмяФайла = ПреобрНазвПолей(НазваниеШаблона, True)
          If Trim(ИмяФайла) = "" Then
            ИмяФайла = Файлы_ВыделитьНазвание(ОбрабатываемыйДокумент.Name) & " (новый)"
          End If
        End If
        ИмяФайла = Файлы_ПроверИмяФайла(ИмяФайла)
        If InStr(1, ИмяФайла, "\") <> 0 Then
        End If
        DoEvents
        КолЗапусков = 0
Заново:
        КолЗапусков = КолЗапусков + 1
        On Error Resume Next
        Err.Clear
        
        ПутьСохранения = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПутьСохранения")
        ПутьСохранения = ПреобрНазвПолей(ЗаменаКонстант(ПутьСохранения))
        ПутьСохранения = Файлы_ПутьАбсол(ПреобрНазвПолей(ПутьСохранения), ОбрабатываемыйДокументPath, True)
        
        If РежимПечати And (ПечатьPDF Or ПечатьDOCX) Then
          If Not ПутьСуществует(ПутьСохранения) Then СоздатьПуть ПутьСохранения
        End If
        
        If Not ПутьСуществует(ПутьСохранения) Then ПутьСохранения = Файлы_ВыделитьПуть(ПутьСохранения)
        If Not ПутьСуществует(ПутьСохранения) Then ПутьСохранения = Файлы_ВыделитьПуть(ПутьСохранения)
        If Файлы_ПутьСущ(ПутьСохранения) And ОчищатьПапку And Not ПринудительноПоОдному Then Файлы_УдалитьПапку ПутьСохранения
        
        Пауза
        If РежимПечати And (ПечатьPDF Or ПечатьDOCX) Then
          If Not ПутьСуществует(ПутьСохранения) Then СоздатьПуть ПутьСохранения
        End If
        
        If ((ПечатьDOCX Or (ПечатьPDF And Not отдельные)) And ПечатьDOCX_ускор) Then
          'Set WordNew = CreateObject("Word.Application")
          ИмяФайла_ = ПутьСохранения & ИмяФайла & ".docx"
          If отдельные Then
            ИмяФайла_2 = ПутьСохранения & ОбрабатываемыйДокумент.Name
            Файлы_КопирФайл ОбрабатываемыйДокументPath & "\" & ОбрабатываемыйДокумент.Name, ИмяФайла_2
            Шаблон = Шаблон2
            DoEvents
            If ОпцияРаботы = ОпцияРаботыМастераШаблоновСтандартная Then ЗапускОднойСтроки Сдвиг, ИмяФайла_2, DocumentXML, ИмяФайла_, Шаблон
            'Doc.SaveAs ИмяФайла_, wdFormatDocumentDefault
            'Doc.Close False
          Else
            If i = 1 Then
              ВремПуть = Файлы_ПутьTemp & "\Assistent\Group"
              Файлы_УдалитьПапку ВремПуть
              Файлы_СоздатьПуть ВремПуть
              МассивФайлов = ""
            End If
            ИмяФайла_2 = ВремПуть & "\Файл_" & i & ".docx"
            Файлы_КопирФайл ОбрабатываемыйДокументPath & "\" & ОбрабатываемыйДокумент.Name, ИмяФайла_2
            Шаблон = Шаблон2
            DoEvents
            If ОпцияРаботы = ОпцияРаботыМастераШаблоновСтандартная Then ЗапускОднойСтроки Сдвиг, ИмяФайла_2, DocumentXML, "Файл_" & i & ".docx", Шаблон
            Массив_Добавить МассивФайлов, ИмяФайла_2
          End If
          
        ElseIf Not отдельные And Not ПечатьDOCX_ускор Then
          ФайлРезультат = ПутьСохранения & ИмяФайла & ".docx"
          If ПервыйЗапуск Then Файлы_Удалить ФайлРезультат: ПервыйЗапуск = False
          ДобавитьТекущийДокументВдругой ОбрабатываемыйДокумент, ФайлРезультат
        ElseIf ПечатьPDF Then
          If ИмяФайла = "" Then
            ИмяФайла_ = Файлы_ПутьTemp & "\Document.pdf"
          Else
            ИмяФайла_ = IIf(Right(ПутьСохранения, 1) = "\", ПутьСохранения, ПутьСохранения & "\") & ИмяФайла & ".pdf"
          End If
          ОбрабатываемыйДокумент.ExportAsFixedFormat OutPutFileName:=ИмяФайла_, ExportFormat:=wdExportFormatPDF
          Er = Err.Number
          КопирФайлДопПути ИмяФайла_
          Err.Number = Er
          
          If ПечатьPDF_принтер Then
            If ПечатьПоследВсеСтр Then
              ОбрабатываемыйДокумент.PrintOut False, Item:=wdPrintDocumentWithMarkup
            Else
              ПечатьДокументаСнастройками
            End If
          End If
        ElseIf ПечатьDOCX Then
          Расш = Mid(DocumentFullName(ОбрабатываемыйДокумент), InStrRev(DocumentFullName(ОбрабатываемыйДокумент), "."))
          If ИмяФайла = "" Then
            ИмяФайла_ = Файлы_ПутьTemp & "\Document" & Расш
          Else
            ИмяФайла_ = IIf(Right(ПутьСохранения, 1) = "\", ПутьСохранения, ПутьСохранения & "\") & ИмяФайла & Расш
          End If
        
          ОбрабатываемыйДокумент.Save
          Файлы_КопирФайл DocumentFullName(ОбрабатываемыйДокумент), ИмяФайла_, True
          Er = Err.Number
          КопирФайлДопПути ИмяФайла_
          Err.Number = Er
          
          If ПечатьPDF_принтер Then
            If ПечатьПоследВсеСтр Then
              ОбрабатываемыйДокумент.PrintOut False, Item:=wdPrintDocumentWithMarkup
            Else
              ПечатьДокументаСнастройками
            End If
          End If
        End If
        
        If Err.Number <> 0 And ИмяФайла <> "" Then
          Resume Повтор
Повтор:
          Err.Clear
          If КолЗапусков >= 10 Then
            MsgBox "Ошибка в процессе генерации. Возможно нет доступа к целевой папке" & vbNewLine & vbNewLine & ПутьСохранения & vbNewLine & vbNewLine & " или имя файла " & vbNewLine & vbNewLine & ИмяФайла_ & vbNewLine & vbNewLine & "недопустимо", vbCritical, "Код ошибки - 1"
            GoTo Завершение
          End If
          GoTo Заново
        ElseIf ИмяФайла_ <> "" Or Not РежимПечати Or (РежимПечати And (Not ПечатьPDF And Not ПечатьПечатьDOCX)) Then
          'Отправка E-mail (при необходимости)
          If ОтпрEmail And ОпцияРаботы <> ОпцияРаботыМастераШаблоновСохранить Then
            If ПечатьPDF Then ИмяФайлаКорр = Файлы_ПутьTemp & "\info.pdf"
            If ПечатьDOCX Then ИмяФайлаКорр = Файлы_ПутьTemp & "\info.docx"
            Файлы_КопирФайл ИмяФайла_, ИмяФайлаКорр
            
            Шаблон = Шаблон2
            Шаблон = ПреобрНазвПолей(Replace(Шаблон, Chr(11), ""))
            ТемаСообщ = ПреобрНазвПолей(ТемаСообщ)
            ИмяОтпр = ПреобрНазвПолей(ИмяОтпр)
            Email = ПреобрНазвПолей(Email)
                        
            If InStr(1, Шаблон, "<") = 0 Then
              'если в сообщении нет тегов, то автоматическая замена переносов строк на </br>
              Шаблон = Replace(Шаблон, vbNewLine, "</br>")
            End If
            
            'Замена ссылок на константы
            Шаблон = ЗаменаКонстант(Шаблон)
            
            If Not (КопияСообщ And ТолькоАдресКопии) Then
              System.Cursor = wdCursorWait
              For k = 1 To Стр_ПослЭлемент(Email, ",")
                АдресОтправки = Стр_ПолучитьЭлемент(Email, k, ",")
                If Not ПечатьPDF And Not ПечатьDOCX Then
                  РезультатОтправки = ОтправитьПисьмо(SMTPсервер, SMTPпорт, SMTPлогин, SMTPпароль, АдресОтправки, ТемаСообщ, ИмяОтпр, Шаблон)
                Else
                  РезультатОтправки = ОтправитьПисьмо(SMTPсервер, SMTPпорт, SMTPлогин, SMTPпароль, АдресОтправки, ТемаСообщ, ИмяОтпр, Шаблон, ИмяФайла_)
                End If
                
                If КопирСообщБуфер Then
                  БуферОбмена_УстанHTML Шаблон
                End If
                
                If ОкноЛога Then
                  If РезультатОтправки = 1 Then
                    ДобавитьЗаписьЛога "Письмо успешно отправлено на адрес " & АдресОтправки
                  Else
                    ДобавитьЗаписьЛога "Ошибка отправки на адрес " & АдресОтправки
                  End If
                End If
              Next k
            End If
            If КопияСообщ Then
              System.Cursor = wdCursorWait
              For k = 1 To Стр_ПослЭлемент(АдресКопииСообщения, ",")
                АдресОтправки = Стр_ПолучитьЭлемент(АдресКопииСообщения, k, ",")
                If Not ПечатьPDF And Not ПечатьDOCX Then
                  РезультатОтправки = ОтправитьПисьмо(SMTPсервер, SMTPпорт, SMTPлогин, SMTPпароль, АдресОтправки, ТемаСообщ, ИмяОтпр, Шаблон)
                Else
                  РезультатОтправки = ОтправитьПисьмо(SMTPсервер, SMTPпорт, SMTPлогин, SMTPпароль, АдресОтправки, ТемаСообщ, ИмяОтпр, Шаблон, ИмяФайла_)
                End If
                
                If КопирСообщБуфер Then
                  БуферОбмена_УстанHTML Шаблон
                End If
                
                If ОкноЛога Then
                  If РезультатОтправки = 1 Then
                    ДобавитьЗаписьЛога "Письмо успешно отправлено на адрес " & АдресОтправки
                  Else
                    ДобавитьЗаписьЛога "Ошибка отправки на адрес " & АдресОтправки
                  End If
                End If
              Next k
            End If
          End If
        End If
        
        ПослСохрФайл = ИмяФайла_
        КолВо = КолВо + 1
      End If
    End If
    System.Cursor = wdCursorWait
    
    If РежимГенерации Then
      Процент = Int(i / МаксПоз * 100)
      If Процент > 100 Then Процент = 100
      Индик_Устан Индикатор_2.Индик, i, , , "Формирование (ESC - Отмена), " & Процент & "%"
    End If
  Next i
  If Not отдельные And ПечатьDOCX_ускор Then
    
    Файлы_СоединитьDOCX МассивФайлов, ИмяФайла_, ThisDocumentPath & "\Ass_Addons"
    Set СущФайл = Documents.Open(ИмяФайла_)
    СущФайл.Activate
    ИмяФайла_Исх = ИмяФайла_
    ИмяФайла_ = ПутьСохранения & ИмяФайла & ".pdf"
    If Распечатать Then СущФайл.PrintOut False, Item:=wdPrintDocumentWithMarkup
    If ПечатьPDF Then
      If ОткрытьПосле Then
        ОбрабатываемыйДокумент.ExportAsFixedFormat OutPutFileName:=ИмяФайла_, ExportFormat:=wdExportFormatPDF, OpenAfterExport:=True
      Else
        ОбрабатываемыйДокумент.ExportAsFixedFormat OutPutFileName:=ИмяФайла_, ExportFormat:=wdExportFormatPDF
      End If
      СущФайл.Close False
      If Not ПоОдному Then
        Файлы_Удалить ИмяФайла_Исх
        Файлы_УдалитьПапку ВремПуть
      End If
    Else
      СущФайл.Save
      If Not ОткрытьПосле Then СущФайл.Close False
    End If
  ElseIf Not отдельные And Not ПечатьDOCX_ускор And (РежимГенерации Or ПослЭлемент) Then
    If ПечатьPDF Then
      ИмяФайлаDocx = ПутьСохранения & ИмяФайла & ".docx"
      ИмяФайлаPdf = ПутьСохранения & ИмяФайла & ".pdf"
      Documents.Open(ИмяФайлаDocx, True, True).ExportAsFixedFormat OutPutFileName:=ИмяФайлаPdf, ExportFormat:=wdExportFormatPDF, OpenAfterExport:=True
      DoEvents
      Documents(ИмяФайлаDocx).Close False
      Файлы_Удалить ИмяФайлаDocx
    End If
  End If
  
  If РежимГенерации Then
    Индикатор_2.Hide
  End If
  
  System.Cursor = wdCursorNormal
  If РежимПечати And (ПечатьPDF Or ПечатьDOCX) And Уведомления Or РежимГенерации Then
    If ИмяФайла <> "" Then
      If IsObject(ОбъединенныйДокумент) Then ОбъединенныйДокумент.Save: ОбъединенныйДокумент.Close
      MsgBox "Генерация завершена! Сформировано " & КолВо & " документов" & vbNewLine & "Время работы - " & ПреобрСек(Timer - НачВремя), vbInformation
    End If
    If РежимГенерации And (ПечатьPDF Or ПечатьDOCX) Then ОткрытьПутьСохранения
  End If
  If ИмяФайла_ = "" And Not ОтпрEmail Then Unload Лог
  
  ОбработкаФлагаЗапуска
  If РежимГенерации Then
    'Нажата кнопка запуск, сброс флага запуска в первоначальное положение
    ФлагЗапуска = 0
  End If
Завершение:
  ActiveWindow.View.ShowHiddenText = ПоказСкрытогоТекста
#If VBA7 Then
  Application.UndoRecord.EndCustomRecord
#End If
End Sub
Sub КопирФайлДопПути(ИмяФайла)
  'Обработка копирования результирующего файла в дополнительные пути
  ПутьСохраненияДоп = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПутьСохраненияДоп")
  ПутьСохраненияДоп = ПреобрНазвПолей(ЗаменаКонстант(ПутьСохраненияДоп))
  
  For w = 1 To Стр_ПослЭлемент(ПутьСохраненияДоп, vbNewLine)
    ПутьСохраненияДопТек = Стр_ПолучитьЭлемент(ПутьСохраненияДоп, w, vbNewLine)
    ПутьСохраненияДопТекРаб = Стр_ПолучитьЭлемент(ПутьСохраненияДопТек, 1, "|")
    ИмяФайлаСохранения = Стр_ПолучитьЭлемент(ПутьСохраненияДопТек, 2, "|")
    If ИмяФайлаСохранения <> "" Then ИмяФайлаСохранения = ПреобрНазвПолей(ИмяФайлаСохранения)
    
    ПутьСохраненияДопТекРаб = ПреобрНазвПолей(ПутьСохраненияДопТекРаб)
    ПутьСохраненияДопТекРаб = Файлы_ПутьАбсол(ПутьСохраненияДопТекРаб, ОбрабатываемыйДокументPath, False)
    Файлы_КопирФайл ИмяФайла, ПутьСохраненияДопТекРаб & IIf(ИмяФайлаСохранения <> "", "\" & ИмяФайлаСохранения & "." & Mid(ИмяФайла, InStrRev(ИмяФайла, ".") + 1), ""), , True
  Next w
End Sub
Function ПреобрНазвПолей(Шаблон, Optional УдалятьПоля = False)
  If Шаблон = "" Then Exit Function
  ПреобрНазвПолей = Шаблон
  ПреобрНазвПолей = Replace(ПреобрНазвПолей, "№", CStr(Позиция))
  КодыПолей = Массив_Сорт(Настр_ПолучПодпапки(Опции_(ПолучитьНомерДокумента), "Поля"), По возрастанию, True)
  
  For z = 1 To 1 + ОбрабатываемыйДокумент.Shapes.Count
    
    If z = 1 Then
      КолПолей = ОбрабатываемыйДокумент.Fields.Count
    Else
      On Error Resume Next
      КолПолей = 0
      КолПолей = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange.Fields.Count
    End If
    
    For i = 1 To КолПолей
      Set Поле = Nothing
      If z = 1 Then
        Сод = ОбрабатываемыйДокумент.Fields(i).Code.text
      Else
        Сод = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange.Fields(i).Code.text
      End If
      
      If InStr(1, UCase(Сод), "SUBJECT") <> 0 Then
        КодПоля = Trim(Стр_ПолучитьЭлемент(Сод, 2, "/"))
        If z = 1 Then
          Set Поле = ОбрабатываемыйДокумент.Fields(i)
        Else
          Set Поле = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange.Fields(i)
        End If
      End If
      
      If Not Поле Is Nothing Then
        ИмяПоля = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "Поля\" & КодПоля, "ИмяПоля")
        Значение = Поле.result
        If УдалятьПоля Then
          ПреобрНазвПолей = Replace(ПреобрНазвПолей, "#" & ИмяПоля & "#", "", , , vbTextCompare)
        Else
          ПреобрНазвПолей = Replace(ПреобрНазвПолей, "#" & ИмяПоля & "#", Значение, , , vbTextCompare)
        End If
      End If
    Next i
  Next z
  ПреобрНазвПолей = Trim(ПреобрНазвПолей)
End Function
Sub ПерейтиКзаписи_(Optional ByVal control As IRibbonControl)
  On Error Resume Next
  If Not ПроверкаДокумента Then Exit Sub
  
  If Not РазрешитьЗапускПремиумФункции Then Exit Sub
  
  ДобЗаписьСтатистИспольз 84
  System.Cursor = wdCursorWait
  ПереходКзаписи.Show
  System.Cursor = wdCursorNormal
End Sub
Sub ПерейтиКзаписи_Клав()
  ПерейтиКзаписи_
End Sub
Sub ЗапускВперед_(Optional ByVal control As IRibbonControl)
  ДобЗаписьСтатистИспольз 85
  ЗапускОднойСтроки 1
End Sub
Sub ЗапускНазад_(Optional ByVal control As IRibbonControl)
  ДобЗаписьСтатистИспольз 86
  ЗапускОднойСтроки -1
End Sub
Function ЗапускОднойСтроки(Направление, Optional ИмяФайлаDocx, Optional ByVal DocumentXML, Optional ByRef ШаблонИмениФайла = "", Optional ByRef ШаблонТекстаСообщения = "", Optional IDполя, Optional ВыводитьФормулуПередРасчетом = False)
  On Error Resume Next
  If Not ОткрытьExcel Then Exit Function
  
#If VBA7 Then
  Application.UndoRecord.StartCustomRecord "Переход к записи"
#End If
  
  KoefStr = 1
  ВремяНачала = Now()
  System.Cursor = wdCursorWait
  If IsMissing(IDполя) Then УдалениеВременныхПолей
  НачСтр = ПолучНачСтр
  Set ТекВыдел = Selection.Range
  
  СловарьВнеш = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "СловарьВнеш"))
  СловарьВсехДок = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "СловарьВсехДок"))
  Словарь = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "Словарь")
  СловарьВнешПуть = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "СловарьВнешПуть")
  РаздельноеОбновление = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "РаздельноеОбновление"))
  Тайминг = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "Тайминг"))
  СтрокаИсточникДанных = Val(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "СтрокаИсточникДанных"))
  If СтрокаИсточникДанных = 0 Then СтрокаИсточникДанных = 1
  ПропускСкрытыйТекст = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "НастройкиПрограммы", "ПропускСкрытыйТекст"))
  
  If ПропускСкрытыйТекст Then ОбрабатываемыйДокумент.Range.Font.Hidden = False
  
  If ШаблонИмениФайла = "" Then ШаблонИмениФайла = Файлы_ВыделитьИмя(ИмяФайлаDocx)
  
  If Not РаздельноеОбновление Then Application.ScreenUpdating = False
  ExcelТек.Parent.Parent.ScreenUpdating = False 'отключение обновления экрана для ускорения работы
  DoEvents
  
  If СловарьВнеш Then
    'Загрузка внешнего словаря
    Путь = Файлы_ПутьАбсол(СловарьВнешПуть, ОбрабатываемыйДокументPath, False)
    If Файлы_ФайлСущ(Путь) Then Словарь = Файлы_ОткрытьФайл(Путь, win)
  ElseIf СловарьВсехДок Then
    'Загрузка словаря всех документов
    Путь = ThisDocumentPath & "\Dictonary.txt"
    If Файлы_ФайлСущ(Путь) Then Словарь = Файлы_ОткрытьФайл(Путь, win)
  End If
  
  Словарь = ЗаменаКонстант(Словарь)
  
  If IsEmpty(Позиция) Then
    Позиция = НачСтр
    If НачСтр = 0 Then Позиция = 1
  Else
    Позиция = Позиция + Направление
    If НачСтр <> 0 And Позиция < НачСтр Then
      Позиция = НачСтр
    ElseIf Позиция < 1 Then
      Позиция = 1
    End If
  End If
  КодыПолей = Массив_Сорт(Настр_ПолучПодпапки(Опции_(ПолучитьНомерДокумента), "Поля"), По возрастанию, True)
  ШаблонИмениФайла = Replace(ШаблонИмениФайла, "№", Позиция)
  ШаблонИмениФайла = ЗаменаКонстант(ШаблонИмениФайла)
  
  'Определение относительной позиции
  ТекПоз = 1
  For z = 1 To UBound(Excel)
    КонСтр = Excel(z).cells(65535, 1).End(-4162).row
    If КонСтр > 32768 Then КонСтр = 32768
    For i = НачСтр To КонСтр
      If ТекПоз = Позиция - НачСтр + 1 Then
        ОтносПозиция = i
        Erase ЛистExcel
        ЛистExcel = Excel(z).Range(Excel(z).cells(1, 1), Excel(z).cells(КонСтр, 250)).Value
        Set ExcelТек = Excel(z)
        GoTo Продолжить
      End If
      ТекПоз = ТекПоз + 1
    Next i
  Next z

Продолжить:
  If IsEmpty(ExcelТек) Then Set ExcelТек = Excel(z - 1)
  ОшибкаSQL = False
  
  'Расчет кол-ва итераций
  КолИтер = ОбрабатываемыйДокумент.Shapes.Count + ОбрабатываемыйДокумент.Fields.Count
  For m = 1 To ОбрабатываемыйДокумент.Shapes.Count
    КолИтер = КолИтер + ОбрабатываемыйДокумент.Shapes(m).TextFrame.TextRange.Fields.Count
  Next m
  Итер = 0
  
  ReDim ОбрабПоля(0)
  
  For z = 1 To 1 + ОбрабатываемыйДокумент.Shapes.Count
      
    КолПолей = 0
    If z = 1 Then
      Set Объект = ОбрабатываемыйДокумент
    Else
      Err.Clear
      Set Объект = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange
      If Err.Number <> 0 Then GoTo Продолж
    End If
    
    КолПолей = Объект.Fields.Count
    System.Cursor = wdCursorWait
    i = 1
    Do While КолПолей > 0
      If ОшибкаSQL Then Application.StatusBar = "Возникла ошибка SQL-запроса при загрузке данных ...": Exit Function
      Set Поле = Nothing
      If z = 1 Then
        Сод = ОбрабатываемыйДокумент.Fields(i).Code.text
        Итер = Итер + 1
      Else
        Сод = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange.Fields(i).Code.text
        Итер = Итер + 1
      End If
      
      If (InStr(1, UCase(Сод), "SUBJECT") <> 0) And (InStr(1, UCase(Сод), "/TEMP") = 0) Then
        КодПоля = Trim(Стр_ПолучитьЭлемент(Сод, 2, "/"))
        If z = 1 Then
          If IsMissing(IDполя) Then Set Поле = ОбрабатываемыйДокумент.Fields(i)
        Else
          If IsMissing(IDполя) Then Set Поле = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange.Fields(i)
        End If
      End If
      
      DoEvents
      If НажатаКлавиша(27) Then
        If ЗапросОстановитьПроцесс Then
          НажатаКлавишаОтмены = True
          Application.StatusBar = "Процесс загрузки данных прерван"
          Индикатор_2.Hide
          ФлагЗапуска = 0
          GoTo Завершение
        End If
      End If
      'MsgBox КодПоля
         
      If ПропускСкрытыйТекст And IsMissing(IDполя) Then
        Поле.Select
        Условие = Not Поле Is Nothing And IsMissing(IDполя) And Not Selection.Font.Hidden
      Else
        Условие = Not Поле Is Nothing And IsMissing(IDполя)
      End If
      
      If Not Условие Then Условие = Not Поле Is Nothing And Val(IDполя) = Val(КодПоля) Or (Not IsMissing(IDполя) And Val(IDполя) = Val(КодПоля))
            
      DoEvents
      If Условие And IsEmpty(Массив_Найти(ОбрабПоля, IDполя)) Then
        If Not IsMissing(IDполя) Then
          If z = 1 Then
            Set Поле = ОбрабатываемыйДокумент.Fields(i)
          Else
            Set Поле = ОбрабатываемыйДокумент.Shapes(z - 1).TextFrame.TextRange.Fields(i)
          End If
        End If
        
        Массив_Добавить ОбрабПоля, IDполя
        ИмяП = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "Поля\" & КодПоля, "ИмяПоля")
               
        ЗагружатьОднократно = False
        ЗагружатьОднократно = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "Поля\" & КодПоля, "ЗагружатьОднократно"))
        
        РассчВложФункц = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "Поля\" & КодПоля, "РассчВложФункц"))
        If Not (ЗагружатьОднократно And ФлагЗапуска = 2) Or Not IsMissing(IDполя) Then
          
          Формула = Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "Поля\" & КодПоля, "Формула")
          СкрытьПустые = CBool(Настр_ЗагрПарам(Опции_(ПолучитьНомерДокумента), "Поля\" & КодПоля, "СкрытьПустые"))
          
          ПростаяСсылка = False
          If Left(Формула, 2) = "=[" And Right(Формула, 1) = "]" And UBound(Split(Формула, "[", 3)) = 1 Then ПростаяСсылка = True
          
          'Замена ссылок на столбцы значением соответствующих ячеек
          If IsEmpty(ЛистExcel) Then
            ЛистExcel = ExcelТек.Range(ExcelТек.cells(1, 1), ExcelТек.cells(КонСтр, 250)).Value
            If IsEmpty(ЛистExcel) Then
              ЛистExcel = ExcelТек.Range(ExcelТек.cells(1, 1), ExcelТек.cells(КонСтр, 250)).Value2
            End If
          End If
          
          Формула = ЗаменаКонстант(Формула)
          Формула = УдалениеКомментариев(Формула)
          
          For k = 1 To 250
            If InStr(1, Формула, "[" & k & "]") <> 0 Then
              If ПростаяСсылка Then
                If IsEmpty(ОтносПозиция) Then
                  Формула = ""
                Else
                  Формула = Replace(Формула, "![" & k & "]", Replace(ЛистExcel(ОтносПозиция, k), """", "''"))
                  Формула = Replace(Формула, "[" & k & "]", """" & Replace(ЛистExcel(ОтносПозиция, k), """", "''") & """")
                End If
              Else
                Формула = Replace(Формула, "[" & k & "]", """" & Replace(ExcelТек.cells(ОтносПозиция, k), """", "''") & """") 'обработка дат
              End If
            End If
            If СтрокаИсточникДанных <> 0 Then
              If InStr(1, Формула, "[" & ЛистExcel(СтрокаИсточникДанных, k) & "]") <> 0 Then
                Формула = Replace(Формула, "![" & ЛистExcel(СтрокаИсточникДанных, k) & "]", Replace(ExcelТек.cells(ОтносПозиция, k), """", "''"))
                Формула = Replace(Формула, "[" & ЛистExcel(СтрокаИсточникДанных, k) & "]", """" & Replace(ExcelТек.cells(ОтносПозиция, k), """", "''") & """")
              End If
            End If
          Next k
          
          'MsgBox Формула
          'DoEvents
          If InStr(1, Формула, "#") <> 0 Then Формула = ЗаменаЗначенийПолей(Формула)
          ТестGIFT = False
          ФормулаДо = Формула
          Формула = РасчетВложенныхФункций(ФормулаДо, Словарь, Поле, z - 1, РассчВложФункц)
          Формула = УдалитьЛишниеЭлементы(Формула)
          Формула = ПодстановкаНомеров(Формула)

          Значение = ""
          
          If ВыводитьФормулуПередРасчетом Then
            If Формула = "=" & """" & """" Or Формула = "" Then
              InputBox ФормулаДо, "", ФормулаДо
            Else
              InputBox Формула, "", Формула
            End If
          End If
          
          If ПростаяСсылка Then
            Значение = Mid(Формула, 3, Len(Формула) - 3)
          Else
            Значение = РасчетФункцийExcel(Формула)
          End If
          
          If ИмяП = "Email" Then Email = Значение
                   
          If IsMissing(ИмяФайлаDocx) Then
            Поле.Code.text = "SUBJECT " & """" & " " & """" & "/" & КодПоля
            'Поле.Update
            
            If ТестGIFT Then
              Значение = ""
            Else
              If Поле.result.text <> Значение Then
                hl = ""
                If Поле.result.Hyperlinks.Count > 0 Then
                  hl = Поле.result.Hyperlinks(1).Address
                End If
                Поле.Update
                Поле.result.text = Значение
                If hl <> "" Then
                  ОбрабатываемыйДокумент.Hyperlinks.Add Поле.result, hl
                End If
              End If
            End If
            
            If СкрытьПустые Then
              If Значение = "" Then
                'Если поле находится в таблице, то скрытие строки таблицы при пустом поле
                Поле.Select
                If Selection.Tables.Count > 0 Then
                  Selection.SelectRow
                  If IsMissing(IDполя) Then Selection.Range.Font.Hidden = True Else Selection.Range.Font.Hidden = False
                Else
                  If Поле.result.Font.Hidden Then
                    Поле.result.Paragraphs(1).Range.Font.Hidden = False
                  End If
                  Selection.Paragraphs(1).Range.Select
                  If IsMissing(IDполя) Then Selection.Range.Font.Hidden = True Else Selection.Range.Font.Hidden = False
                End If
              Else
                If Поле.result.Tables.Count > 0 Then
                  Поле.result.Rows(1).Range.Font.Hidden = False
                  If Err.Number = 5991 Then Поле.result.Tables(1).Range.Font.Hidden = False
                Else
                  If Selection.Paragraphs(1).Range.Font.Hidden Then Selection.Paragraphs(1).Range.Font.Hidden = False
                End If
              End If
            End If
          
            'Распознавание знака вертикальной или горизонтальной табуляции для разделения ячеек таблицы
            If InStr(1, Значение, Chr(11)) <> 0 Or InStr(1, Значение, Chr(9)) <> 0 Then
              Поле.Select
              If Selection.Tables.Count > 0 Then
                КодПоля = Поле.Code.text
                
                If Left(Значение, 1) = Chr(11) Then Значение = Mid(Значение, 2)
                'Do
                '  Значение = Replace(Значение, Chr(11) & Chr(11), Chr(11))
                '  If InStr(1, Значение, Chr(11) & Chr(11)) = 0 Then Exit Do
                'Loop
                If Right(Значение, 1) = Chr(11) Then Значение = Mid(Значение, 1, Len(Значение) - 1)
                
                КолСтрок = Стр_ПослЭлемент(Значение, Chr(11))
                ЗначМассива = Стр_ПолучитьЭлемент(Значение, 1, Chr(11))
                КолСтолб = Стр_ПослЭлемент(ЗначМассива, Chr(9))
                НачСтр = IIf(КолСтолб > 1, 1, 2) '1 - обработка таблицы; 2 - обработка столбца
                
                Поле.result.text = Стр_ПолучитьЭлемент(ЗначМассива, 1, Chr(9))
                РезПол = Поле.result.text
                
                'Проверка необходимости вставки требуемого количества строк
                Стр = Selection.cells(1).RowIndex
                Стб = Selection.cells(1).ColumnIndex
                Сод = ""
                ЕстьЗаполнСтроки = False
                For h = Стр + 1 To Стр + КолСтрок - 1
                  For G = Стб To IIf(КолСтолб > 1, Selection.Tables(1).Columns.Count, 0) 'Отключение проверки заполнения нижележащих ячеек для одного столбца с данными
                    Сод = Сод & Selection.Tables(1).Cell(h, G).Range.text
                    Сод = Replace(Сод, Chr(13), "")
                    Сод = Replace(Сод, Chr(7), "")
                    If Сод <> "" Then ЕстьЗаполнСтроки = True: Exit For
                  Next G
                  If Сод <> "" Then ЕстьЗаполнСтроки = True: Exit For
                Next h
                If Selection.Tables(1).Rows.Count < Стр + КолСтрок - 1 Or ЕстьЗаполнСтроки Then
                  Поле.Select
                  Selection.SelectCell
                  DoEvents
                  
                  Err.Clear
                  
                  Selection.Tables(1).Select
                  Selection.MoveDown
                  If Selection.Tables.Count = 0 Then
                    Поле.Select
                    Selection.SelectCell
                    
                    Selection.InsertBreak Type:=wdColumnBreak
                    Selection.Expand wdCharacter
                    Selection.Delete wdCharacter, 1
                  End If
                  
                  Set Поле = НайтиПоле(Стр_ПолучитьЭлемент(КодПоля, 2, "/"))
                  Поле.Select
                  Selection.Tables(1).Rows.Add
                  Selection.EndKey Unit:=wdColumn, Extend:=True
                  Selection.Collapse wdCollapseEnd
                  Selection.SelectRow
                  Selection.Rows.Delete
                  Поле.Select
                  Selection.SelectRow
                  'Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove
                  ОбрабатываемыйДокумент.Options.CheckSpellingAsYouType = False
                  Selection.InsertRowsBelow 1
                  DoEvents
                  
                  'Selection.MoveUp Unit:=wdLine, Count:=1, Extend:=wdMove
                  'Selection.SelectRow
                  Selection.Collapse
                  DoEvents
                  'Selection.Paste
                  If (КолСтрок - 2) > 0 Then Selection.InsertRows КолСтрок - 2
                End If
                
                'Set Поле = ОбрабатываемыйДокумент.Fields(I)
                
                If КолСтолб > 1 Then
                  'Заполение массива данными
                  Поле.Select
                  Selection.Collapse
                  
                  'ЗначОбнЭкр = Application.ScreenUpdating
                  DoEvents
                  'Application.ScreenUpdating = False
                  'Application.ScreenUpdating = True
                  
                  'Selection.InsertAfter Значение
                  DoEvents
                                        
                  'Selection.Cut
                  'Application.ScreenUpdating = ЗначОбнЭкр
                  
                  Set Поле = НайтиПоле(Стр_ПолучитьЭлемент(КодПоля, 2, "/"))
                  Поле.Select
                  
                  'Пауза
                  
                  НачВыд = Selection.start
                  
                  НачСтр = Selection.cells(1).RowIndex
                  НачСтолб = Selection.cells(1).ColumnIndex
                  Selection.Tables(1).Cell(НачСтр + КолСтрок - 1, НачСтолб + КолСтолб - 1).Select
                  КонВыд = Selection.End
                  
                  If z > 1 Then
                    Поле.Select
                    Set ИсхФайлДиап = Selection.Tables(1).Range
                  Else
                    Set ИсхФайлДиап = ActiveDocument.Range(НачВыд, КонВыд)
                  End If
                  
                  КолСтб = ИсхФайлДиап.Columns.Count
                  КолСтр = ИсхФайлДиап.Rows.Count
                  
                  DoEvents
                  
                  Яч = 0
                  For Lin = 1 To КолСтр
                    For col = 1 To КолСтб
                      Яч = Яч + 1
                      If z > 1 Then
                        If Lin >= НачСтр And col >= НачСтолб Then
                          ЗначЯчSQL = Стр_ПолучитьЭлемент(Значение, Lin - (НачСтр - 1), Chr(11))
                          ЗначЯчSQL = Стр_ПолучитьЭлемент(ЗначЯчSQL, col - (НачСтолб - 1), vbTab)
…
vbaProject_00.bin🔏 SignedVBA project digital signature
Covers VBA source only — not the compiled p-code. A digital signature does not by itself mean the macro is safe.
vba-project OOXML VBA project: word/vbaProject.bin 4734976 bytes
SHA-256: 319139e36b13cefe0a963ea512c7cfad1f43b76e0e36ee0cd684a66bd8d3aba0
Detection
ClamAV: Doc.Downloader.Pwshell-10001336-0
Obfuscation or payload: likely
1278 of 1948 identifiers look randomly generated (e.g. 'kbOxwrX9yeZe9jLFu0kMoWxe4Tqko9I1xrVZFRED'); 21 string-concatenation chain(s) — consistent with name-mangling obfuscation. Carved artifact contains 56 long base64-like blob(s).