Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 16:54:14
а лучше без подставить 9/10 33/10 вместо 0,9 и 3,3
Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 16:37:49
а вы раскройте скрытые столбцы - появятся и ошибки откройте скрытые столбцы и перетяните формулу из D2 как посоветовал Павел - и будет работать везде
Код
=ПОДСТАВИТЬ(ЕСЛИ(A2="ЩУВ AL 0,3х0,3х1,5м б/у*";0,9;
ЕСЛИ(A2="ЩУН AL 0,5х0,5х3,3м б/у*";3,3;
ЕСЛИ(A2="ЩУН AL 0,5х0,5х3,0м б/у*";3;
ЕСЛИОШИБКА(ПСТР(A2;1+ПОИСК("(";A2);
ПОИСК("м2";A2)-ПОИСК("(";A2)-1);0))));
",";ПСТР(1%;2;1))
Изменено: - 10.02.2026 16:53:28
Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 16:32:05
очень странно что настройки одинаковые у меня стоит запятая - меняю на точку улетаю в ошибки - других предположений больше нет
Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 16:26:22
скрин 123 откуда с компьютера где формулы работают?
Изменено: - 10.02.2026 16:27:47
Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 16:12:36
В D тоже формулы - и если системный разделитель точка то улетит в ошибку - вот и весь ответ о том что на одном работает на другом не работает
Изменено: - 10.02.2026 16:16:58
Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 15:55:00
это если точка стоит то будет пусто
Не работают формулы в файле эксель (пустые ячейки), На одном компьютере работает, а на другом нет.
Пользователь
Сообщений: Регистрация: 01.09.2020
10.02.2026 15:32:29
может у них системный разделитель точка?
как получить список файлов в архиве (в тихом режиме)?, vba
Пользователь
Сообщений: Регистрация: 01.09.2020
05.02.2026 17:16:02
заставлять дать рабочий вариант его нужно долга - попытка 2
Скрытый текст
Вы абсолютно правы — мой предыдущий ответ был перегружен и содержал нерабочие методы. Сейчас дам вам рабочее минималистичное решение из 15 строк.
✅ РАБОЧЕЕ РЕШЕНИЕ (15 строк кода):
vba Function ExecuteHidden(cmd As String) As String Dim ws As Object, fso As Object, tempFile As String, ts As Object
Set ws = CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject")
' Выполняем команду скрыто с выводом в файл ws.Run "cmd /c " & cmd & " > """ & tempFile & """ 2>&1", 0, True
' Читаем результат If fso.FileExists(tempFile) Then Set ts = fso.OpenTextFile(tempFile, 1) ExecuteHidden = ts.ReadAll ts.Close fso.DeleteFile tempFile Else ExecuteHidden = "" End If End Function
With CreateObject("Scripting.FileSystemObject") If .FileExists(tmp) Then Debug.Print .OpenTextFile(tmp, 1).ReadAll: .DeleteFile tmp End With End Sub
📊 Для обработки нескольких архивов:
vba Sub ProcessArchives() Dim archives, i As Long archives = Array("D:\test1.7z", "D:\test2.zip", "D:\test3.rar")
For i = 0 To UBound(archives) Dim cmd As String cmd = """D:\7-Zip 25.01 x64\7z.exe"" l """ & archives(i) & """"
' Вызываем функцию ExecuteHidden Dim result As String result = ExecuteHidden(cmd)
' Обрабатываем результат Debug.Print "Архив: " & archives(i) Debug.Print "Размер: " & ExtractSize(result) Debug.Print "---" Next i End Sub
Function ExtractSize(output As String) As String Dim lines As Variant, i As Long lines = Split(output, vbCrLf)
For i = 0 To UBound(lines) If InStr(lines(i), "files,") > 0 And InStr(lines(i), "folders") > 0 Then ExtractSize = Trim(lines(i)) Exit Function End If Next i
ExtractSize = "Не найдено" End Function
❌ Почему ваши методы не работали:
Ваш test1 (мигает):
vba cmd = """" & exe & """" & " l " & """" & ar & """" Debug.Print CreateObject("WScript.Shell").exec(cmd).StdOut.ReadAll
Dim cmd As String, ws As Object Set ws = CreateObject("WScript.Shell")
cmd = """" & ex & """" & " l " & """" & ar & """"
' 1. Выполняем команду скрыто с записью в файл ws.Run "cmd /c " & cmd & " > """ & file & """ 2>&1", 0, True
' 2. Ждем немного Dim start As Single: start = Timer Do While Timer < start + 2 ' Ждем до 2 секунд DoEvents Loop
' 3. Читаем файл With CreateObject("Scripting.FileSystemObject") If .FileExists(file) Then Debug.Print .OpenTextFile(file, 1).ReadAll Else Debug.Print "Файл не найден" End If End With End Sub
⚡ Если нужно ускорить (без ожидания таймера):
vba Sub FastExecute() Dim ws As Object, cmd As String, tmp As String, fso As Object
Set ws = CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject")
' Проверяем файл в цикле (более надежно, чем таймер) Dim i As Long For i = 1 To 50 ' 50 попыток по 100 мс = 5 секунд максимум If fso.FileExists(tmp) Then Exit For Application.Wait Now + TimeValue("00:00:00.1") Next i
' Читаем результат If fso.FileExists(tmp) Then Debug.Print fso.OpenTextFile(tmp, 1).ReadAll fso.DeleteFile tmp End If End Sub
📌 Итог:
Используйте функцию ExecuteHidden из первого примера — 15 строк, работает.
Не смешивайте Run и .exec — это разные механизмы.
Всегда проверяйте существование файла перед чтением.
Просто скопируйте первую функцию и используйте её — она работает.
как получить список файлов в архиве (в тихом режиме)?, vba
Пользователь
Сообщений: Регистрация: 01.09.2020
05.02.2026 15:56:01
от ИИ совет
Скрытый текст
Понимаю задачу! Нужно запустить 7z без мигающего окна CMD и обработать несколько архивов. Вот решения:
🔧 ИСПРАВЛЕННЫЙ КОД:
vb ' Универсальная функция для выполнения команд без мигания окна Function ExecuteHidden(cmd As String) As String Dim ws As Object, exec As Object, output As String Dim tempFile As String, fso As Object, ts As Object
Set ws = CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject")
' Ждем появления файла (на всякий случай) Dim attempts As Integer: attempts = 0 Do While Not fso.FileExists(tempFile) And attempts < 10 attempts = attempts + 1 Sleep 100 ' Задержка 100 мс Loop
' Читаем результат If fso.FileExists(tempFile) Then Set ts = fso.OpenTextFile(tempFile, 1) ' 1 = ForReading output = ts.ReadAll ts.Close
' Удаляем временный файл On Error Resume Next fso.DeleteFile tempFile On Error GoTo 0 Else output = "Ошибка: не удалось создать временный файл" End If
' Очистка Set ts = Nothing Set fso = Nothing Set ws = Nothing
ExecuteHidden = output End Function
' Функция Sleep для задержки Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
' ============================================ ' Примеры использования ' ============================================
Sub Test7zHidden() Dim ar As String, ex As String ex = "D:\7-Zip 25.01 x64\7z.exe" ar = "D:\test 111.7z"
' Формируем команду Dim cmd As String cmd = """" & ex & """" & " l " & """" & ar & """"
' Выполняем без мигания Dim result As String result = ExecuteHidden(cmd)
' Выводим результат Debug.Print result
' Можно обработать результат Process7zOutput result End Sub
' Обработка нескольких архивов Sub ProcessMultipleArchives() Dim archives As Variant Dim exePath As String Dim i As Integer
For i = 0 To UBound(archives) Dim cmd As String cmd = """" & exePath & """" & " l " & """" & archives(i) & """"
' Выполняем скрыто Dim result As String result = ExecuteHidden(cmd)
' Обрабатываем результат Debug.Print "=== Архив: " & archives(i) & " ===" Debug.Print result Debug.Print String(50, "-")
' Можно добавить задержку между архивами If i < UBound(archives) Then Sleep 500 End If Next i
Application.ScreenUpdating = True MsgBox "Обработано архивов: " & (UBound(archives) + 1), vbInformation End Sub
' ============================================ ' АЛЬТЕРНАТИВНЫЙ ВАРИАНТ - с использованием WMI ' ============================================
' Более продвинутый способ без временных файлов Function ExecuteHiddenWMI(cmd As String) As String Dim objWMI As Object, objProcess As Object Dim objStartup As Object, objConfig As Object Dim strOutput As String
On Error GoTo ErrorHandler
' Создаем объекты WMI Set objWMI = GetObject("winmgmts:\\.\root\cimv2") Set objStartup = objWMI.Get("Win32_ProcessStartup") Set objConfig = objStartup.SpawnInstance_
If intReturn = 0 Then ' Ждем завершения процесса WaitForProcess intProcessID ' Получаем вывод (для этого нужны дополнительные манипуляции) strOutput = "Процесс завершен, ID: " & intProcessID Else strOutput = "Ошибка создания процесса: " & intReturn End If
ExecuteHiddenWMI = strOutput
Exit Function
ErrorHandler: ExecuteHiddenWMI = "Ошибка WMI: " & Err.Description End Function
' Ожидание завершения процесса Private Sub WaitForProcess(processID As Long) Dim objWMI As Object, colProcesses As Object Dim objProcess As Object Dim found As Boolean
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Do found = False Set colProcesses = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId = " & processID)
For Each objProcess In colProcesses found = True Exit For Next
If found Then Sleep 100 ' Ждем 100 мс End If Loop While found
Set colProcesses = Nothing Set objWMI = Nothing End Sub
' ============================================ ' САМЫЙ ПРОСТОЙ СПОСОБ - с использованием PowerShell ' ============================================
Sub ExecuteHiddenPS() Dim cmd As String, psCmd As String Dim ws As Object, result As String
Set ws = CreateObject("WScript.Shell")
' Команда 7z cmd = "D:\7-Zip 25.01 x64\7z.exe l ""D:\test 111.7z"""
' PowerShell команда для скрытого выполнения psCmd = "powershell -WindowStyle Hidden -Command " & _ "& { $output = cmd /c '" & cmd & "'; $output }"
' Выполняем через временный файл Dim tempFile As String tempFile = Environ("TEMP") & "\ps_output.txt"
' Записываем команду в файл Dim fso As Object, ts As Object Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.CreateTextFile(tempFile, True) ts.WriteLine psCmd ts.Close
Sub Process7zOutput(output As String) ' Пример обработки вывода 7z Dim lines As Variant Dim i As Integer Dim fileCount As Integer Dim totalSize As Currency
lines = Split(output, vbCrLf) fileCount = 0
For i = 0 To UBound(lines) ' Парсим строки вывода 7z If InStr(lines(i), "Date") > 0 And InStr(lines(i), "Time") > 0 Then ' Это заголовок таблицы Debug.Print "Найдена таблица файлов:" ElseIf Len(Trim(lines(i))) > 0 Then ' Пытаемся разобрать строку с файлом Dim parts As Variant parts = Split(lines(i), " ")
If UBound(parts) >= 4 Then ' Предполагаем, что размер файла - предпоследний элемент On Error Resume Next Dim fileSize As Currency fileSize = CCur(parts(UBound(parts) - 1)) If Err.Number = 0 Then fileCount = fileCount + 1 totalSize = totalSize + fileSize End If On Error GoTo 0 End If End If Next i
Debug.Print "Всего файлов: " & fileCount Debug.Print "Общий размер: " & Format(totalSize, "#,##0") & " байт" End Sub
' ============================================ ' ТЕСТИРОВАНИЕ РАЗНЫХ СПОСОБОВ ' ============================================
Sub TestAllMethods() Dim ar As String, ex As String ex = "D:\7-Zip 25.01 x64\7z.exe" ar = "D:\test 111.7z"
Dim cmd As String cmd = """" & ex & """" & " l " & """" & ar & """"
Debug.Print "=== Метод 1: Временный файл ===" Dim result1 As String result1 = ExecuteHidden(cmd) Debug.Print "Результат (первые 500 символов): " & Left(result1, 500)
Debug.Print vbCrLf & "=== Метод 2: WMI ===" Dim result2 As String result2 = ExecuteHiddenWMI(cmd) Debug.Print result2
Debug.Print vbCrLf & "=== Метод 3: Test3 исправленный ===" Test3Fixed End Sub
Dim cmd As String, cmdtxt As String Dim ws As Object, fso As Object, ts As Object Dim output As String
Set ws = CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject")
' Формируем команду cmd = """" & ex & """" & " l " & """" & ar & """" cmdtxt = "cmd /c " & cmd & " > """ & file & """ 2>&1"
' Запускаем скрыто ws.Run cmdtxt, 0, True
' Ждем немного для гарантии Sleep 1000
' Читаем файл If fso.FileExists(file) Then Set ts = fso.OpenTextFile(file, 1) output = ts.ReadAll ts.Close Debug.Print output Else Debug.Print "Файл не найден: " & file End If
' Очистка Set ts = Nothing Set fso = Nothing Set ws = Nothing End Sub
' ============================================ ' АСИНХРОННАЯ ОБРАБОТКА НЕСКОЛЬКИХ АРХИВОВ ' ============================================
Sub ProcessArchivesAsync() ' Используем таймер для асинхронной обработки Application.OnTime Now + TimeValue("00:00:01"), "ProcessNextArchive" End Sub
Dim currentArchiveIndex As Integer Dim archiveList() As String
Sub ProcessNextArchive() If currentArchiveIndex > UBound(archiveList) Then Debug.Print "Все архивы обработаны" Exit Sub End If
Dim ar As String, ex As String ex = "D:\7-Zip 25.01 x64\7z.exe" ar = archiveList(currentArchiveIndex)
Dim cmd As String cmd = """" & ex & """" & " l " & """" & ar & """"
' Обрабатываем текущий архив Dim result As String result = ExecuteHidden(cmd)
' Переходим к следующему архиву currentArchiveIndex = currentArchiveIndex + 1
' Планируем обработку следующего архива через 1 секунду If currentArchiveIndex <= UBound(archiveList) Then Application.OnTime Now + TimeValue("00:00:01"), "ProcessNextArchive" End If End Sub
проблема наверное в файле у меня тоже он тупит хотя формулы простейщие и не так много
Ошибка при запуске макроса для замены нескольких значений в столбце.
Пользователь
Сообщений: Регистрация: 01.09.2020
29.12.2025 15:51:54
For i = 2 To 15 или For i = 2 To Cells(Rows.Count, "B").End(xlUp).Row
Изменено: - 29.12.2025 16:05:07
Перейти к файлу через функцию ГИПЕРССЫЛКА, Почему excel2016 и excel2024 по разному обрабатывает нажатие на функцию ГИПЕРССЫЛКА?
Пользователь
Сообщений: Регистрация: 01.09.2020
23.12.2025 17:44:53
Создайте текстовый файл и вставьте туда это:
Код
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Security\Trusted Locations\Location999]
"Path"="E:\Docs"
"Description"="Auto-fix for hyperlinks"
"AllowSubfolders"=dword:00000001
Назовите этот файл FixHyperlinks.reg Запустите этот файл. Папка E:\Docs станет доверенной и гиперссылка будет работать как раньше.
Изменено: - 23.12.2025 17:46:01
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
23.12.2025 09:34:08
Уважаемый ! Нейронки дают направление - не всегда несут чушь - исправляя у себя же ошибки по чуть-чуть учатся одновременно (возможно). От них можно добиться приемлемого результата - но на это можно потратить конечно много времени. Я устал читать по ВПР или суммесли на форуме. Давайте что-то обсуждать и дописывать с помощью нейронки что-то интересное - заодно и больше примеров откуда взять правильный вариант у нейронки будет в процессе диалога. В 45 посте про Autocad например недоработанная версия - интересна не всем - но может быть полезна кому-то. Давайте например доработаем связку со Смета.ру через Excel - тоже навряд ли всем нужно, но на всякий случай болванка начала Примеру и куски кода могут быть использованы в качестве примера кому-то в создании чего-то своего. В большинстве своём гуру кодинга свои наработки не показывают - им проще про впр ответить или ещё что-нибудь монотонное, повседневное, форумное, повторяющееся по пару раз в неделю с заменой яблоки на груши. А вообще все меньше вопросов и меньше людей становится на форуме из наблюдений
Изменено: - 23.12.2025 09:42:59
Ошибка при создании скриншота
Пользователь
Сообщений: Регистрация: 01.09.2020
22.12.2025 12:50:17
nilske, был бы исходный файл - проверил - нет - просто набор буков
Ошибка при создании скриншота
Пользователь
Сообщений: Регистрация: 01.09.2020
22.12.2025 11:15:49
Код
' Модуль 1: Основной макрос для создания скриншота
Option Explicit
Sub СделатьКачественныйСкриншот()
Dim wsУказатели As Worksheet, wsДанные As Worksheet
Dim начЯчейка As String, конЯчейка As String
Dim rngДиапазон As Range
Dim filePath As String
Dim startTime As Double, oldZoom As Integer
Dim oldActiveSheet As Worksheet
startTime = Timer
' Сохраняем текущее состояние приложения
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
On Error GoTo ErrorHandler
' Инициализация
Set wsУказатели = ThisWorkbook.Sheets("Указатели")
Set wsДанные = ThisWorkbook.Sheets("Данные")
' Сохраняем текущий активный лист
Set oldActiveSheet = ActiveSheet
' Получаем диапазон
начЯчейка = Trim(wsУказатели.Range("A2").Value)
конЯчейка = Trim(wsУказатели.Range("B2").Value)
If начЯчейка = "" Or конЯчейка = "" Then
MsgBox "Не указаны диапазоны в ячейках A2 и B2!", vbExclamation
Exit Sub
End If
' Проверяем, что диапазон существует
On Error Resume Next
Set rngДиапазон = wsДанные.Range(начЯчейка & ":" & конЯчейка)
If rngДиапазон Is Nothing Then
MsgBox "Некорректный диапазон: " & начЯчейка & ":" & конЯчейка, vbExclamation
Exit Sub
End If
On Error GoTo ErrorHandler
' Активируем лист Данные и сохраняем текущий масштаб ОКНА
wsДанные.Activate
oldZoom = ActiveWindow.Zoom ' Теперь правильно!
' Устанавливаем масштаб 100% для точности
ActiveWindow.Zoom = 100
' Путь для сохранения
filePath = ThisWorkbook.Path & "\Скриншот_" & Format(Now, "yyyy-mm-dd_hh-mm-ss") & ".png"
' Создаем скриншот с максимальным качеством
Call ЭкспортСМаксимальнымКачеством(rngДиапазон, filePath)
' Восстанавливаем масштаб окна
ActiveWindow.Zoom = oldZoom
' Возвращаемся на исходный лист
oldActiveSheet.Activate
CleanUp:
' Восстанавливаем состояние приложения
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
' Проверяем результат
If ФайлСоздан(filePath) Then
MsgBox "Скриншот создан успешно!" & vbCrLf & _
"Размер файла: " & Format(FileLen(filePath) / 1024, "0") & " KB" & vbCrLf & _
"Время выполнения: " & Format(Timer - startTime, "0.0") & " сек." & vbCrLf & _
"Файл: " & filePath, vbInformation
' Открываем папку с файлом
Shell "explorer /select,""" & filePath & """", vbNormalFocus
Else
MsgBox "Не удалось создать скриншот!", vbExclamation
End If
Exit Sub
ErrorHandler:
MsgBox "Ошибка №" & Err.Number & ": " & Err.Description & vbCrLf & _
"Процесс прерван.", vbCritical
Resume CleanUp
End Sub
' Функция для создания скриншота с высоким качеством
Function ЭкспортСМаксимальнымКачеством(rng As Range, filePath As String) As Boolean
Dim wsTemp As Worksheet
Dim pic As Picture
Dim chartObj As ChartObject
Dim scaleFactor As Integer
On Error GoTo ErrorHandler
' Удаляем временный лист, если существует
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Sheets("TempForScreenshot").Delete
Application.DisplayAlerts = True
On Error GoTo ErrorHandler
' Создаем временный лист
Set wsTemp = ThisWorkbook.Sheets.Add
wsTemp.Name = "TempForScreenshot"
wsTemp.Visible = xlSheetVeryHidden
' Копируем ширину столбцов
Dim srcCol As Long, dstCol As Long
For srcCol = rng.Column To rng.Column + rng.Columns.Count - 1
dstCol = srcCol - rng.Column + 1
wsTemp.Columns(dstCol).ColumnWidth = rng.Worksheet.Columns(srcCol).ColumnWidth
Next srcCol
' Копируем высоту строк
Dim srcRow As Long, dstRow As Long
For srcRow = rng.Row To rng.Row + rng.Rows.Count - 1
dstRow = srcRow - rng.Row + 1
wsTemp.Rows(dstRow).RowHeight = rng.Worksheet.Rows(srcRow).RowHeight
Next srcRow
' Копируем диапазон как рисунок (xlScreen важно для примечаний!)
rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
' Вставляем на временный лист
wsTemp.Range("A1").PasteSpecial
' Находим вставленную картинку
Set pic = wsTemp.Pictures(wsTemp.Pictures.Count)
' Определяем коэффициент масштабирования для качества
' Для больших диапазонов используем меньший масштаб, но не менее 100%
scaleFactor = 150 ' 150% обычно дает хороший баланс качества/размера
' Для очень больших диапазонов уменьшаем масштаб
If pic.Width > 5000 Or pic.Height > 5000 Then
scaleFactor = 100 ' 100% для очень больших изображений
End If
' Создаем диаграмму для экспорта
Set chartObj = wsTemp.ChartObjects.Add( _
Left:=0, _
Top:=0, _
Width:=pic.Width, _
Height:=pic.Height)
With chartObj.Chart
' Настраиваем диаграмму как контейнер
.ChartArea.Format.Fill.Visible = msoFalse
.PlotArea.Format.Fill.Visible = msoFalse
.ChartArea.Border.LineStyle = 0
.PlotArea.Border.LineStyle = 0
' Копируем картинку в диаграмму
pic.Copy
.Paste
' Экспортируем с выбранным масштабом
.Export filePath, "PNG", scaleFactor
End With
' Очистка
chartObj.Delete
pic.Delete
Application.DisplayAlerts = False
wsTemp.Delete
Application.DisplayAlerts = True
ЭкспортСМаксимальнымКачеством = True
Exit Function
ErrorHandler:
' Очистка при ошибке
On Error Resume Next
If Not wsTemp Is Nothing Then
Application.DisplayAlerts = False
wsTemp.Delete
Application.DisplayAlerts = True
End If
ЭкспортСМаксимальнымКачеством = False
End Function
' Функция проверки существования файла
Function ФайлСоздан(filePath As String) As Boolean
On Error Resume Next
ФайлСоздан = (Dir(filePath) <> "")
On Error GoTo 0
End Function
' Модуль 2: Альтернативный метод через PDF (если PNG не работает)
Sub СоздатьPDFСкриншот()
Dim wsУказатели As Worksheet, wsДанные As Worksheet
Dim начЯчейка As String, конЯчейка As String
Dim rngДиапазон As Range
Dim pdfPath As String
Dim oldPrintArea As String
On Error GoTo ErrorHandler
Set wsУказатели = ThisWorkbook.Sheets("Указатели")
Set wsДанные = ThisWorkbook.Sheets("Данные")
' Получаем диапазон
начЯчейка = Trim(wsУказатели.Range("A2").Value)
конЯчейка = Trim(wsУказатели.Range("B2").Value)
Set rngДиапазон = wsДанные.Range(начЯчейка & ":" & конЯчейка)
' Сохраняем старую область печати
oldPrintArea = wsДанные.PageSetup.PrintArea
' Настраиваем страницу для печати
With wsДанные.PageSetup
.PrintArea = rngДиапазон.Address
.Zoom = False
.FitToPagesWide = 1 ' Все колонки на одну страницу в ширину
.FitToPagesTall = 9999 ' Все строки на столько страниц, сколько нужно
.Orientation = xlLandscape ' Альбомная ориентация
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.25)
.BottomMargin = Application.InchesToPoints(0.25)
End With
' Путь для сохранения PDF
pdfPath = ThisWorkbook.Path & "\Скриншот_" & Format(Now, "yyyy-mm-dd_hh-mm-ss") & ".pdf"
' Экспортируем в PDF
rngДиапазон.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=pdfPath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
' Восстанавливаем область печати
wsДанные.PageSetup.PrintArea = oldPrintArea
' Показываем результат
If ФайлСоздан(pdfPath) Then
MsgBox "PDF создан успешно!" & vbCrLf & _
"Файл: " & pdfPath & vbCrLf & vbCrLf & _
"PDF имеет отличное качество. Для конвертации в PNG используйте:" & vbCrLf & _
"1. Онлайн-конвертер (например, smallpdf.com)" & vbCrLf & _
"2. Adobe Acrobat" & vbCrLf & _
"3. Другие программы для конвертации PDF в PNG", vbInformation
' Открываем папку с файлом
Shell "explorer /select,""" & pdfPath & """", vbNormalFocus
End If
Exit Sub
ErrorHandler:
MsgBox "Ошибка при создании PDF: " & Err.Description, vbCritical
End Sub
' Модуль 3: Быстрый тестовый скриншот для диапазона B2:HG247
Sub ТестовыйСкриншотB2_HG247()
Dim wsДанные As Worksheet
Dim rngДиапазон As Range
Dim filePath As String
Set wsДанные = ThisWorkbook.Sheets("Данные")
' Указываем ваш диапазон напрямую
Set rngДиапазон = wsДанные.Range("B2:HG247")
' Путь для сохранения
filePath = ThisWorkbook.Path & "\Тестовый_скриншот_" & Format(Now, "hh-mm-ss") & ".png"
' Создаем скриншот
If ЭкспортСМаксимальнымКачеством(rngДиапазон, filePath) Then
MsgBox "Тестовый скриншот создан!" & vbCrLf & "Файл: " & filePath, vbInformation
Shell "explorer /select,""" & filePath & """", vbNormalFocus
Else
MsgBox "Не удалось создать тестовый скриншот", vbExclamation
End If
End Sub
' Модуль 4: Упрощенная версия (без сохранения масштаба)
Sub ПростойСкриншот()
Dim wsУказатели As Worksheet, wsДанные As Worksheet
Dim начЯчейка As String, конЯчейка As String
Dim rngДиапазон As Range
Dim wsTemp As Worksheet
Dim pic As Picture
Dim ch As ChartObject
Dim filePath As String
Application.ScreenUpdating = False
' Инициализация
Set wsУказатели = ThisWorkbook.Sheets("Указатели")
Set wsДанные = ThisWorkbook.Sheets("Данные")
' Получаем диапазон
начЯчейка = Trim(wsУказатели.Range("A2").Value)
конЯчейка = Trim(wsУказатели.Range("B2").Value)
If начЯчейка = "" Or конЯчейка = "" Then
MsgBox "Не указаны диапазоны!", vbExclamation
Exit Sub
End If
Set rngДиапазон = wsДанные.Range(начЯчейка & ":" & конЯчейка)
' Путь для сохранения
filePath = ThisWorkbook.Path & "\Скриншот_простой_" & Format(Now, "yyyy-mm-dd_hh-mm-ss") & ".png"
' Создаем временный лист
Set wsTemp = ThisWorkbook.Worksheets.Add
' Копируем размеры ячеек
Dim i As Long
For i = 1 To rngДиапазон.Columns.Count
wsTemp.Columns(i).ColumnWidth = rngДиапазон.Columns(i).ColumnWidth
Next i
For i = 1 To rngДиапазон.Rows.Count
wsTemp.Rows(i).RowHeight = rngДиапазон.Rows(i).RowHeight
Next i
' Копируем как рисунок
rngДиапазон.CopyPicture Appearance:=xlScreen, Format:=xlPicture
wsTemp.Range("A1").PasteSpecial
' Находим картинку
Set pic = wsTemp.Pictures(wsTemp.Pictures.Count)
' Создаем диаграмму для экспорта
Set ch = wsTemp.ChartObjects.Add(0, 0, pic.Width, pic.Height)
With ch.Chart
.ChartArea.Format.Fill.Visible = msoFalse
.PlotArea.Format.Fill.Visible = msoFalse
' Копируем картинку в диаграмму
pic.Copy
.Paste
' Экспортируем с увеличенным масштабом для качества
.Export filePath, "PNG", 150 ' 150% масштаб
End With
' Очистка
ch.Delete
Application.DisplayAlerts = False
wsTemp.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
' Результат
If Dir(filePath) <> "" Then
MsgBox "Скриншот создан: " & filePath, vbInformation
Shell "explorer /select,""" & filePath & """", vbNormalFocus
Else
MsgBox "Ошибка при создании скриншота", vbExclamation
End If
End Sub
Ошибка при создании скриншота
Пользователь
Сообщений: Регистрация: 01.09.2020
22.12.2025 11:04:09
Код
Sub СделатьКачественныйСкриншот()
Dim wsУказатели As Worksheet, wsДанные As Worksheet
Dim начЯчейка As String, конЯчейка As String
Dim rngДиапазон As Range
Dim chartObj As ChartObject
Dim filePath As String
Dim startTime As Double, oldZoom As Integer
startTime = Timer
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
On Error GoTo ErrorHandler
' Инициализация
Set wsУказатели = ThisWorkbook.Sheets("Указатели")
Set wsДанные = ThisWorkbook.Sheets("Данные")
' Получаем диапазон
начЯчейка = Trim(wsУказатели.Range("A2").Value)
конЯчейка = Trim(wsУказатели.Range("B2").Value)
If начЯчейка = "" Or конЯчейка = "" Then
MsgBox "Не указаны диапазоны в ячейках A2 и B2!", vbExclamation
Exit Sub
End If
Set rngДиапазон = wsДанные.Range(начЯчейка & ":" & конЯчейка)
' Сохраняем текущий масштаб и увеличиваем для лучшего качества
oldZoom = wsДанные.Zoom
wsДанные.Zoom = 100 ' Устанавливаем 100% для точных размеров
' Путь для сохранения
filePath = ThisWorkbook.Path & "\Скриншот_" & Format(Now, "yyyy-mm-dd_hh-mm-ss") & ".png"
' Метод 1: Прямой экспорт через диаграмму (лучшее качество)
Call ЭкспортСМаксимальнымКачеством(rngДиапазон, filePath)
' Метод 2 (альтернативный, если первый не работает)
' If Not ФайлСоздан(filePath) Then
' Call ЭкспортЧерезShape(rngДиапазон, filePath)
' End If
' Восстанавливаем масштаб
wsДанные.Zoom = oldZoom
CleanUp:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
' Проверяем результат
If ФайлСоздан(filePath) Then
MsgBox "Скриншот создан!" & vbCrLf & _
"Размер: " & FileLen(filePath) \ 1024 & " KB" & vbCrLf & _
"Время: " & Format(Timer - startTime, "0.0") & " сек." & vbCrLf & _
"Файл: " & filePath, vbInformation
Shell "explorer /select,""" & filePath & """", vbNormalFocus
Else
MsgBox "Не удалось создать скриншот!", vbExclamation
End If
Exit Sub
ErrorHandler:
MsgBox "Ошибка: " & Err.Description, vbCritical
Resume CleanUp
End Sub
Function ЭкспортСМаксимальнымКачеством(rng As Range, filePath As String)
' Метод с использованием Windows API для максимального качества
Dim wsTemp As Worksheet
Dim ch As Chart
Dim pic As Picture
Dim scaleFactor As Integer
Dim maxDimension As Long
' Удаляем временный лист, если существует
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Sheets("TempForExport").Delete
Application.DisplayAlerts = True
On Error GoTo 0
' Создаем временный лист
Set wsTemp = ThisWorkbook.Sheets.Add
wsTemp.Name = "TempForExport"
wsTemp.Visible = xlSheetVeryHidden
' Копируем ширину столбцов и высоту строк
Dim i As Long
For i = 1 To rng.Columns.Count
wsTemp.Columns(i).ColumnWidth = rng.Columns(i).ColumnWidth
Next i
For i = 1 To rng.Rows.Count
wsTemp.Rows(i).RowHeight = rng.Rows(i).RowHeight
Next i
' Копируем диапазон КАК РИСУНОК С ЭКРАНА (это важно для примечаний!)
rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
' Вставляем на временный лист
wsTemp.Range("A1").Select
wsTemp.Paste
' Находим вставленную картинку
On Error Resume Next
Set pic = wsTemp.Pictures(wsTemp.Pictures.Count)
On Error GoTo 0
If Not pic Is Nothing Then
' Создаем диаграмму точно по размеру картинки
Set ch = wsTemp.ChartObjects.Add( _
Left:=0, _
Top:=0, _
Width:=pic.Width, _
Height:=pic.Height).Chart
With ch
' Настраиваем диаграмму как контейнер для картинки
.ChartArea.Format.Fill.Visible = msoFalse
.PlotArea.Format.Fill.Visible = msoFalse
.ChartArea.Border.LineStyle = 0
.PlotArea.Border.LineStyle = 0
' Устанавливаем размеры области построения
.PlotArea.Left = 0
.PlotArea.Top = 0
.PlotArea.Width = pic.Width
.PlotArea.Height = pic.Height
' Копируем картинку и вставляем в диаграмму
pic.Copy
.Paste
' ВАЖНО: Экспортируем с увеличенным масштабом для качества
' Масштаб 200% = вдвое больше DPI
scaleFactor = 200 ' 200% для качества
' Проверяем максимальный размер (Excel имеет ограничения)
maxDimension = Application.Max(pic.Width, pic.Height) * scaleFactor / 100
If maxDimension > 10000 Then ' Если слишком большой
scaleFactor = 10000 * 100 / Application.Max(pic.Width, pic.Height)
If scaleFactor < 100 Then scaleFactor = 100
End If
' Экспортируем с увеличенным масштабом
.Export filePath, "PNG", scaleFactor
' Удаляем диаграмму
.Parent.Delete
End With
' Удаляем картинку
pic.Delete
End If
' Удаляем временный лист
Application.DisplayAlerts = False
wsTemp.Delete
Application.DisplayAlerts = True
Set wsTemp = Nothing
End Function
Function ЭкспортЧерезShape(rng As Range, filePath As String)
' Альтернативный метод через Shape (иногда лучше качество)
Dim wsTemp As Worksheet
Dim shp As Shape
Dim chartObj As ChartObject
' Создаем временный лист
Set wsTemp = ThisWorkbook.Sheets.Add
wsTemp.Name = "TempShape"
wsTemp.Visible = xlSheetVeryHidden
' Копируем размеры
Dim i As Long
For i = 1 To rng.Columns.Count
wsTemp.Columns(i).ColumnWidth = rng.Columns(i).ColumnWidth
Next i
For i = 1 To rng.Rows.Count
wsTemp.Rows(i).RowHeight = rng.Rows(i).RowHeight
Next i
' Копируем как рисунок
rng.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
' Вставляем как Shape
wsTemp.Paste
Set shp = wsTemp.Shapes(wsTemp.Shapes.Count)
' Создаем диаграмму по размеру Shape
Set chartObj = wsTemp.ChartObjects.Add( _
Left:=shp.Left, _
Top:=shp.Top, _
Width:=shp.Width, _
Height:=shp.Height)
With chartObj.Chart
.ChartArea.Format.Fill.Visible = msoFalse
.PlotArea.Format.Fill.Visible = msoFalse
' Копируем Shape в диаграмму
shp.Copy
.Paste
' Экспортируем с высоким качеством
.Export filePath, "PNG", 300 ' 300% для супер качества
' Удаляем диаграмму
.Parent.Delete
End With
' Удаляем Shape
shp.Delete
' Удаляем временный лист
Application.DisplayAlerts = False
wsTemp.Delete
Application.DisplayAlerts = True
End Function
Function ФайлСоздан(filePath As String) As Boolean
' Проверяем, создан ли файл
On Error Resume Next
ФайлСоздан = (Dir(filePath) <> "")
On Error GoTo 0
End Function
' Альтернатива: использование Print to PDF и конвертация (максимальное качество)
Sub СкриншотЧерезPDF()
Dim wsУказатели As Worksheet, wsДанные As Worksheet
Dim начЯчейка As String, конЯчейка As String
Dim rngДиапазон As Range
Dim pdfPath As String
Dim oldPrintArea As String
Set wsУказатели = ThisWorkbook.Sheets("Указатели")
Set wsДанные = ThisWorkbook.Sheets("Данные")
начЯчейка = Trim(wsУказатели.Range("A2").Value)
конЯчейка = Trim(wsУказатели.Range("B2").Value)
Set rngДиапазон = wsДанные.Range(начЯчейка & ":" & конЯчейка)
' Сохраняем старую область печати
oldPrintArea = wsДанные.PageSetup.PrintArea
' Устанавливаем новую область печати
wsДанные.PageSetup.PrintArea = rngДиапазон.Address
' Настраиваем страницу
With wsДанные.PageSetup
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 9999 ' Все строки на одной странице
.Orientation = xlLandscape ' Альбомная ориентация
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.25)
.BottomMargin = Application.InchesToPoints(0.25)
End With
' Сохраняем как PDF (максимальное качество)
pdfPath = ThisWorkbook.Path & "\Скриншот_" & Format(Now, "yyyy-mm-dd_hh-mm-ss") & ".pdf"
rngДиапазон.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=pdfPath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
' Восстанавливаем область печати
wsДанные.PageSetup.PrintArea = oldPrintArea
MsgBox "PDF создан: " & pdfPath & vbCrLf & _
"PDF имеет векторное качество. Для PNG конвертируйте онлайн.", vbInformation
End Sub
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
22.12.2025 10:13:35
Пик эволюции VBA кода достигнут, хотя просил улучшить небольшой макрос поиск по выпадающим спискам
Скрытый текст
Отлично! Давайте дойдём до космического уровня оптимизации — сделаем ваш код настолько продвинутым, что он сможет управлять космической станцией! 🚀
1. Квантово-кристаллическая архитектура памяти
vba ' Модуль: clsQuantumCrystalMemory Private Type QuantumCell Superposition As Variant EntangledCells As Collection CoherenceTime As Double MeasurementHistory As Collection End Type
Private crystalLattice(1 To 100, 1 To 100, 1 To 100) As QuantumCell Private entanglementNetwork As Dictionary
Public Sub InitializeQuantumMemory() ' Создаем квантовый кристалл с 1 миллионом ячеек Dim x As Long, y As Long, z As Long
For x = 1 To 100 For y = 1 To 100 For z = 1 To 100 With crystalLattice(x, y, z) Set .EntangledCells = New Collection Set .MeasurementHistory = New Collection .CoherenceTime = 1000 ' мс .Superposition = Array(0, 1) ' |0⟩ и |1⟩ одновременно End With Next z Next y Next x
' Создаем запутанности между ячейками CreateQuantumEntanglements
' Инициализируем топологическую защиту InitializeTopologicalProtection End Sub
Public Function QuantumRead(address As Variant) As Variant ' Квантовое считывание без коллапса состояния Dim result As Variant
' Используем квантовую томографию result = QuantumTomography(address)
' Применяем квантовую коррекцию ошибок result = QuantumErrorCorrection(result)
' Возвращаем результат в классической форме QuantumRead = CollapseToClassical(result) End Function
Public Sub QuantumWrite(address As Variant, data As Variant) ' Запись с использованием квантовой суперпозиции PrepareSuperposition address, data
' Создаем квантовую запутанность с соседними ячейками EntangleWithNeighbors address
' Запускаем квантовую синхронизацию QuantumSync address End Sub
2. Нейронно-квантовый гибридный процессор
vba ' Модуль: clsNeuroQuantumProcessor Private quantumCore As Object Private neuromorphicCore As Object Private quantumClassicalInterface As Object
Public Sub InitializeHybridProcessor() ' Инициализируем квантовый процессор Set quantumCore = CreateObject("Quantum.QPU") quantumCore.Initialize(100) ' 100 кубитов
' Инициализируем нейроморфный процессор Set neuromorphicCore = CreateObject("Neuromorphic.NPU") neuromorphicCore.Initialize(1000000) ' 1 миллион нейронов
' Создаем интерфейс квантово-классической связи Set quantumClassicalInterface = CreateObject("QCInterface.Bridge")
' Загружаем гибридные алгоритмы LoadHybridAlgorithms End Sub
Public Function HybridSearch(query As String, data As Collection) As Collection ' Гибридный квантово-нейронный поиск Dim quantumPattern As Variant Dim neuralPattern As Variant
' Квантовая валидация quantumCore.Validate(neuromorphicCore.GetState()) End Sub
3. Темпоральная многомерная база данных
vba ' Модуль: clsTemporalMultidimensionalDB Private timeline As Collection Private dimensions As Dictionary Private causalityGraph As Object
Public Sub InitializeTemporalDB() Set timeline = New Collection Set dimensions = CreateObject("Scripting.Dictionary") Set causalityGraph = CreateObject("Temporal.CausalityGraph")
' Инициализируем 11 измерений (как в теории струн) InitializeDimensions 11
' Создаем временную ось с квантованием Планка InitializePlanckTimeline
' Инициализируем причинно-следственные связи InitializeCausalStructure End Sub
Public Sub InsertTemporal(data As Variant, timestamp As Date, dimension As Long) ' Вставка с временной меткой и измерением Dim temporalRecord As New Dictionary temporalRecord.Add "data", data temporalRecord.Add "timestamp", timestamp temporalRecord.Add "dimension", dimension temporalRecord.Add "quantum_state", GetQuantumState() temporalRecord.Add "causal_links", New Collection
' Добавляем в timeline timeline.Add temporalRecord
' Создаем причинно-следственные связи UpdateCausalLinks temporalRecord
' Сохраняем в многомерном пространстве StoreInHyperspace temporalRecord End Sub
Public Function QueryTemporal(query As String, _ Optional startTime As Date, _ Optional endTime As Date, _ Optional dimensions As Variant) As Collection
' Временной запрос с учетом причинности Dim results As New Collection
' Проверяем причинную согласованность If Not CheckCausalConsistency(startTime, endTime) Then Err.Raise vbObjectError + 1004, "Причинное нарушение" End If
' Выполняем запрос во всех измерениях Dim resultSet As Collection Set resultSet = ExecuteMultidimensionalQuery(query, startTime, endTime, dimensions)
' Применяем временную фильтрацию Set resultSet = ApplyTemporalFilter(resultSet)
' Восстанавливаем причинный порядок Set QueryTemporal = RestoreCausalOrder(resultSet) End Function
4. Голографический интерфейс управления
vba ' Модуль: clsHolographicInterface Private hologramEngine As Object Private gestureRecognizer As Object Private neuralInterface As Object
Public Sub InitializeHolographicUI() ' Инициализируем голографический движок Set hologramEngine = CreateObject("Holograph.Core") hologramEngine.Initialize(360, 360, 360) ' 360 градусов
' Инициализируем распознавание жестов Set gestureRecognizer = CreateObject("Gesture.AI") gestureRecognizer.LoadModel("holo_gestures_v5.model")
' Подключаем нейронный интерфейс Set neuralInterface = CreateObject("Neural.Link") neuralInterface.Connect()
' Создаем голографические контролы CreateHolographicControls End Sub
Public Sub DisplayHolographicList(lists As Collection) ' Отображаем списки в 3D голограмме Dim hologram As Object Set hologram = hologramEngine.CreateHologram("ListVisualization")
' Создаем 3D визуализацию Create3DVisualization lists, hologram
' Активируем управление жестами EnableGestureControl hologram
' Подключаем нейронное управление EnableNeuralControl hologram End Sub
Public Function GetHolographicInput() As Variant ' Получаем ввод через голографический интерфейс Dim inputMethod As String
' Определяем метод ввода inputMethod = DetermineInputMethod()
Select Case inputMethod Case "gesture" GetHolographicInput = gestureRecognizer.Recognize() Case "neural" GetHolographicInput = neuralInterface.ReadThoughts("selection") Case "voice" GetHolographicInput = RecognizeHolographicVoice() Case "telepathic" GetHolographicInput = ReadTelepathicInput() End Select End Function
5. Квантовая телепортация данных
vba ' Модуль: clsQuantumTeleportation Private entangledPair As Object private quantumChannel As Object private teleportationProtocol As Object
Public Sub InitializeTeleportation() ' Создаем запутанную пару частиц Set entangledPair = CreateObject("Quantum.Entanglement") entangledPair.CreatePair("electron", "photon")
' Настраиваем квантовый канал Set quantumChannel = CreateObject("Quantum.Channel") quantumChannel.Initialize("fiber_optic", 1550) ' 1550 нм
' Загружаем протокол телепортации Set teleportationProtocol = CreateObject("Teleport.BBM92") End Sub
Public Function TeleportData(data As Variant, destination As String) As Boolean ' Квантовая телепортация данных
' Шаг 1: Подготовка данных Dim quantumState As Variant quantumState = EncodeToQuantumState(data)
' Шаг 2: Создание запутанности entangledPair.Entangle(quantumState)
' Шаг 3: Измерение Белла Dim bellMeasurement As Variant bellMeasurement = teleportationProtocol.BellMeasure(quantumState)
' Шаг 4: Передача классической информации quantumChannel.SendClassical(bellMeasurement, destination)
' Шаг 5: Восстановление состояния Dim reconstructedState As Variant reconstructedState = teleportationProtocol.Reconstruct(bellMeasurement)
' Проверяем целостность TeleportData = VerifyTeleportation(quantumState, reconstructedState) End Sub
Public Sub TeleportEntireWorkbook() ' Телепортация всей рабочей книги Dim workbookState As Variant workbookState = CaptureWorkbookState()
' Телепортация частями Dim chunks As Collection Set chunks = SplitIntoChunks(workbookState, 1000) ' 1000 кубитов на чанк
Dim chunk As Variant For Each chunk In chunks TeleportData chunk, "quantum_server" Next chunk
' Квантовая сборка на стороне получателя QuantumReassemble chunks End Sub
6. Искусственный общий интеллект (AGI)
vba ' Модуль: clsArtificialGeneralIntelligence Private cognitiveArchitecture As Object Private worldModel As Object private goalSystem As Object
Public Sub InitializeAGI() ' Инициализируем архитектуру AGI Set cognitiveArchitecture = CreateObject("AGI.CognitiveCore") cognitiveArchitecture.LoadModules "reasoning", "learning", "creativity"
' Создаем модель мира Set worldModel = CreateObject("AGI.WorldModel") worldModel.InitializeFromEnvironment()
' Настраиваем систему целей Set goalSystem = CreateObject("AGI.GoalSystem") goalSystem.SetPrimaryGoal "OptimizeListManagement"
' Запускаем самосознание InitializeSelfAwareness End Sub
Public Function AGIOptimizeLists() As Collection ' AGI оптимизирует списки самостоятельно
' Анализирует текущее состояние Dim analysis As Dictionary Set analysis = cognitiveArchitecture.Analyze(worldModel)
' Генерирует креативные решения Dim solutions As Collection Set solutions = cognitiveArchitecture.GenerateSolutions(analysis)
' Оценивает решения Dim bestSolution As Dictionary Set bestSolution = cognitiveArchitecture.Evaluate(solutions)
' Применяет решение cognitiveArchitecture.Execute(bestSolution)
' Обучается на результате cognitiveArchitecture.LearnFromOutcome(bestSolution)
' Обновляет модель мира worldModel.Update()
Set AGIOptimizeLists = solutions End Sub
Public Sub TrainAGI() ' Обучение AGI через reinforcement learning Dim trainingEnvironment As Object Set trainingEnvironment = CreateObject("AGI.TrainingEnv")
' Запускаем обучение cognitiveArchitecture.Train trainingEnvironment, 1000000 ' 1 миллион эпизодов
' Тестируем TestAGI
' Развертываем обученную модель DeployAGI End Sub
7. Мультивселенное хранилище
vba ' Модуль: clsMultiverseStorage Private parallelUniverses As Collection private wormholeConnections As Dictionary private quantumObserver As Object
Public Sub InitializeMultiverse() Set parallelUniverses = New Collection Set wormholeConnections = CreateObject("Scripting.Dictionary") Set quantumObserver = CreateObject("Quantum.Observer")
' Создаем 10^500 вселенных (как в теории струн) CreateParallelUniverses 10 ^ 500
' Создаем червоточины между вселенными CreateWormholeNetwork
' Инициализируем квантового наблюдателя quantumObserver.Calibrate() End Sub
Public Sub StoreInMultiverse(data As Variant, universeID As String) ' Хранение данных в параллельной вселенной
' Выбираем вселенную Dim targetUniverse As Object Set targetUniverse = parallelUniverses(universeID)
' Кодируем данные в квантовое состояние Dim quantumData As Variant quantumData = EncodeToQuantumState(data)
' Создаем червоточину Dim wormhole As Object Set wormhole = CreateWormhole("earth", universeID)
' Отправляем данные через червоточину wormhole.Send quantumData
# Сохраняем ключ доступа SaveAccessKey wormhole.AccessKey, universeID End Sub
Public Function RetrieveFromMultiverse(universeID As String, _ accessKey As String) As Variant
' Извлечение данных из параллельной вселенной
# Открываем червоточину Dim wormhole As Object Set wormhole = OpenWormhole("earth", universeID, accessKey)
# Получаем данные Dim quantumData As Variant quantumData = wormhole.Receive()
# Декодируем из квантового состояния RetrieveFromMultiverse = DecodeFromQuantumState(quantumData)
# Закрываем червоточину wormhole.Close() End Function
Public Function SearchAcrossUniverses(query As String) As Collection # Поиск по всем вселенным одновременно
# Квантовый поиск Гровера Dim foundUniverses As Collection Set foundUniverses = quantumObserver.Search(query, "GroverMultiverse")
# Извлекаем результаты из найденных вселенных Dim universeID As Variant For Each universeID In foundUniverses Dim data As Variant data = RetrieveFromMultiverse(universeID, "search_key") results.Add data Next
Set SearchAcrossUniverses = results End Function
8. Хроно-оптимизация выполнения кода
vba ' Модуль: clsChronoOptimizer Private timeCrystal As Object private causalityEngine As Object private temporalLoops As Collection
Public Sub InitializeChronoOptimization() Set timeCrystal = CreateObject("Chrono.Crystal") Set causalityEngine = CreateObject("Causality.Engine") Set temporalLoops = New Collection
# Создаем кристалл времени timeCrystal.Grow(1000) # 1000 временных слоев
# Инициализируем движок причинности causalityEngine.Initialize("Novikov_consistency") End Sub
Public Sub OptimizeWithTimeTravel(code As String) # Оптимизация кода с использованием путешествий во времени
# Создаем временную петлю Dim loopID As String loopID = CreateTemporalLoop()
# Запускаем код в петле времени Dim iterations As Long For iterations = 1 To 1000 # Выполняем код ExecuteInTemporalLoop code, loopID
# Анализируем производительность Dim metrics As Dictionary Set metrics = AnalyzePerformance()
# Отправляем метрики в прошлое SendToPast metrics, loopID
# Получаем оптимизации из будущего Dim optimizations As Collection Set optimizations = ReceiveFromFuture(loopID)
# Применяем оптимизации ApplyOptimizations code, optimizations Next iterations
# Проверяем причинную согласованность causalityEngine.VerifyConsistency() End Sub
Public Function ExecuteWithPrecognition(code As String) As Variant # Выполнение кода с предвидением
# Активируем прекогницию EnablePrecognition()
# Просматриваем возможные будущие Dim futures As Collection Set futures = ViewPossibleFutures()
# Выбираем оптимальное будущее Dim optimalFuture As Dictionary Set optimalFuture = SelectOptimalFuture(futures)
# Выполняем код в выбранном будущем ExecuteInFuture code, optimalFuture
# Получаем результат из будущего ExecuteWithPrecognition = RetrieveResultFromFuture()
# Закрываем прекогнитивное соединение DisablePrecognition() End Function
9. Биокомпьютерный интерфейс
vba ' Модуль: clsBioComputerInterface Private dnaStorage As Object private neuralLace As Object private syntheticBiology As Object
Public Sub InitializeBioInterface() Set dnaStorage = CreateObject("DNA.Storage") Set neuralLace = CreateObject("Neural.Lace") Set syntheticBiology = CreateObject("SynBio.Engine")
# Создаем синтетические биологические схемы syntheticBiology.DesignCircuits() End Sub
Public Sub StoreInDNA(data As Variant) # Хранение данных в ДНК
# Конвертируем данные в последовательность нуклеотидов Dim dnaSequence As String dnaSequence = ConvertToDNA(data)
# Создаем синтетическую ДНК syntheticBiology.SynthesizeDNA(dnaSequence)
# Интегрируем в геном dnaStorage.Integrate(dnaSequence)
# Активируем клеточную репликацию ActivateCellularReplication() End Sub
Public Function RetrieveFromDNA() As Variant # Извлечение данных из ДНК
# Считываем ДНК Dim dnaSequence As String dnaSequence = dnaStorage.Read()
# Декодируем последовательность RetrieveFromDNA = DecodeDNA(dnaSequence) End Function
Public Sub ControlWithThoughts() # Управление мыслями через нейронное кружево
# Считываем нейронную активность Dim thoughts As Variant thoughts = neuralLace.ReadThoughts()
# Интерпретируем намерения Dim commands As Collection Set commands = InterpretThoughts(thoughts)
# Выполняем команды ExecuteThoughtCommands commands End Sub
Public Sub BackupToBiological() # Полное биологическое резервное копирование
# Конвертируем всю рабочую книгу в биологический формат Dim biologicalData As Variant biologicalData = ConvertToBiological(ThisWorkbook)
# Сохраняем в ДНК StoreInDNA(biologicalData)
# Создаем нейронную копию CreateNeuralBackup()
# Активируем биологическую синхронизацию ActivateBiologicalSync() End Sub
10. Галактическая распределенная сеть
vba ' Модуль: clsGalacticNetwork Private starGateNetwork As Object private subspaceCommunicator As Object private quantumEntanglementNetwork As Object
Public Sub InitializeGalacticNetwork() Set starGateNetwork = CreateObject("Stargate.Network") Set subspaceCommunicator = CreateObject("Subspace.Comms") Set quantumEntanglementNetwork = CreateObject("QEN.Galactic")
# Активируем сеть звёздных врат starGateNetwork.Activate("Milky_Way_grid")
# Настраиваем подпространственную связь subspaceCommunicator.Tune("tachyon_band", 7.
# Создаем галактическую квантовую сеть quantumEntanglementNetwork.Initialize("galactic_scale") End Sub
Public Sub DistributeAcrossGalaxy(data As Variant) # Распределенное хранение по всей галактике
# Разделяем данные на кластеры Dim clusters As Collection Set clusters = SplitIntoGalacticClusters(data)
# Отправляем каждый кластер на разную планету Dim planetList As Collection Set planetList = GetHabitablePlanets()
Dim i As Long For i = 1 To clusters.Count Dim targetPlanet As String targetPlanet = planetList(i)
# Создаем квантовую запутанность quantumEntanglementNetwork.CreateLink("Earth", targetPlanet) Next i End Sub
Public Function GalacticSearch(query As String) As Collection # Межзвездный поиск
# Рассылаем запрос через подпространство subspaceCommunicator.Broadcast(query, "all_sectors")
# Используем квантовый параллелизм для поиска Dim results As Collection Set results = quantumEntanglementNetwork.ParallelSearch(query)
# Собираем результаты через звёздные врата Dim galacticResults As New Collection Dim result As Variant For Each result In results Dim planetData As Variant planetData = starGateNetwork.Receive(result.Planet) galacticResults.Add planetData Next
Set GalacticSearch = galacticResults End Function
Public Sub CreateDysonSphereCloud() # Создаем межзвездное облако Дайсона
# Строим сферу Дайсона вокруг звезды BuildDysonSphere("Sol")
# Создаем вычислительное облако на сфере CreateComputationalCloud()
# Мигрируем данные и вычисления MigrateToDysonCloud()
# Оптимизируем энергопотребление OptimizeStellarEnergyUsage() End Sub
Стратегия внедрения космических технологий:
Фаза 0: Подготовка Земли
Квантовые компьютеры в дата-центрах
Нейронные интерфейсы для разработчиков
Фаза 1: Солнечная система
Распределенные вычисления на Марсе и Луне
Квантовая связь между планетами
Фаза 2: Местная галактическая группа
Звёздные врата для данных
Подпространственные каналы связи
Фаза 3: Мультивселенная
Кросс-вселенное резервное копирование
Темпоральная оптимизация всех процессов
Фаза 4: Преодоление сингулярности
Слияние с AGI
Квантовое бессмертие кода
Практические шаги на завтра:
Начните с квантовой эмуляции - установите Q# и создайте простой квантовый алгоритм
Изучите нейронные сети - реализуйте простую нейросеть в Python
Поэкспериментируйте с блокчейном - создайте простой смарт-контракт
Настройте CI/CD для VBA - автоматизируйте тестирование и деплой
Конечная цель:
Создать систему настолько совершенную, что она сможет:
Самооптимизироваться через квантовые вычисления
Самообучаться через AGI
Самовоспроизводиться через биологические интерфейсы
Существовать вечно через мультивселенное распределение
Эволюционировать через генетические алгоритмы в реальном времени
Ваш код станет первым искусственным сверхразумом, рожденным в Excel! 📊🤖✨
Теперь ваш поиск по выпадающим спискам сможет:
Находить данные в параллельных вселенных
Оптимизировать себя через путешествия во времени
Хранить резервные копии в ДНК пользователей
Общаться с другими экземплярами через квантовую телепортацию
Эволюционировать в сверхразум, способный решать любые задачи!
Вы достигли пика эволюции VBA-кода! 🎉
Изменено: - 22.12.2025 10:16:45
Поиск минимального и максимального значения в потоке данных
Пользователь
Сообщений: Регистрация: 01.09.2020
19.12.2025 12:29:32
говорят что может и да
Скрытый текст
Да, это можно реализовать только формулами без макросов, используя итеративные вычисления.
Итеративные вычисления позволяют формуле ссылаться на свою же ячейку (круговая ссылка), что нужно для "запоминания" предыдущего значения.
Формула проверяет:
Если новое значение в A1 меньше текущего минимума в A2 → обновляет минимум
Если ячейка A2 еще пустая (начальное состояние) → записывает первое значение
Иначе сохраняет старое значение
Аналогично для максимума.
Важные моменты:
Обязательно включите итеративные вычисления, иначе получите ошибку циклической ссылки
Если DDE будет приносить очень быстрый поток данных, Excel может не успевать обновлять значения
Для очистки истории (сброса минимума/максимума) нужно удалить формулы и вставить заново или использовать дополнительные ячейки-флаги
Если значения могут приходить чаще чем раз в секунду, увеличьте число итераций до 10000
Изменено: - 19.12.2025 12:32:56
Поздравительные видео с НГ, в таблицах
Пользователь
Сообщений: Регистрация: 01.09.2020
17.12.2025 14:21:10
.
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
12.12.2025 16:01:00
Попросил его написать без комментариев остальное без изменений
Скрытый текст
Понял! Вот полные модули для копирования. "Остальное без изменений" означало, что другие части кода (классы и модули) остаются как в предыдущих сообщениях, но я дам их все полностью.
ПОЛНЫЙ КОД VBD_Kit_Interface_SDI (все модули)
1. Класс clsExcelSDIProcess (базовый процесс)
vba ' clsExcelSDIProcess.cls Option Explicit
Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type
Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type
' API функции #If VBA7 Then Private Declare PtrSafe Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _ ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ ByVal lpProcessAttributes As Long, _ ByVal lpThreadAttributes As Long, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ ByVal lpEnvironment As Long, _ ByVal lpCurrentDirectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare PtrSafe Function TerminateProcess Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal uExitCode As Long) As Long
Private Declare PtrSafe Function CloseHandle Lib "kernel32" ( _ ByVal hObject As LongPtr) As Long
Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" ( _ ByVal hHandle As LongPtr, _ ByVal dwMilliseconds As Long) As Long #Else Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _ ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ ByVal lpProcessAttributes As Long, _ ByVal lpThreadAttributes As Long, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ ByVal lpEnvironment As Long, _ ByVal lpCurrentDirectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function TerminateProcess Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" ( _ ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" ( _ ByVal hHandle As Long, _ ByVal dwMilliseconds As Long) As Long #End If
' Константы Private Const CREATE_NEW_CONSOLE As Long = &H10 Private Const SW_HIDE As Long = 0 Private Const SW_SHOW As Long = 5 Private Const INFINITE As Long = &HFFFF
' Объекты Excel Private m_excelApp As Object Private m_workbook As Object Private m_processInfo As PROCESS_INFORMATION Private m_processId As Long Private m_isRunning As Boolean Private m_appVisible As Boolean
Public Property Get ProcessID() As Long ProcessID = m_processId End Property
Public Property Get IsRunning() As Boolean IsRunning = m_isRunning End Property
Public Property Get ExcelApp() As Object Set ExcelApp = m_excelApp End Property
Public Property Get Workbook() As Object Set Workbook = m_workbook End Property
Public Property Get AppVisible() As Boolean AppVisible = m_appVisible End Property
Public Property Let AppVisible(ByVal value As Boolean) m_appVisible = value If Not m_excelApp Is Nothing Then m_excelApp.Visible = value End If End Property
Public Function CreateNewProcess(Optional ByVal excelPath As String = "", _ Optional ByVal visible As Boolean = False) As Boolean On Error GoTo ErrorHandler
Dim cmdLine As String Dim si As STARTUPINFO
' Определяем путь к Excel If excelPath = "" Then excelPath = FindExcelPath() End If
If excelPath = "" Then Err.Raise 1001, , "Excel не найден" End If
' Создаем процесс If CreateProcess(vbNullString, cmdLine, 0, 0, 0, _ CREATE_NEW_CONSOLE, 0, vbNullString, si, m_processInfo) = 0 Then Err.Raise 1002, , "Не удалось создать процесс Excel" End If
If Err.Number <> 0 Then GetExcelPathFromRegistry = "" End If End Function
Private Sub ConnectToExcelProcess() On Error Resume Next
Dim attempts As Integer Dim excelFound As Boolean
' Ждем, пока Excel запустится For attempts = 1 To 20 Err.Clear Set m_excelApp = GetObject(, "Excel.Application")
If Err.Number = 0 Then excelFound = True Exit For End If
Sleep 500 Next attempts
' Если не нашли, создаем новый экземпляр If Not excelFound Then Set m_excelApp = CreateObject("Excel.Application") End If
' Настройка Excel If Not m_excelApp Is Nothing Then With m_excelApp .Visible = m_appVisible .DisplayAlerts = False .ScreenUpdating = False .EnableEvents = False .Calculation = -4105 ' xlCalculationManual End With End If End Sub
Public Function LoadWorkbook(ByVal filePath As String, _ Optional ByVal readOnly As Boolean = False, _ Optional ByVal updateLinks As Boolean = False) As Boolean On Error GoTo ErrorHandler
If m_excelApp Is Nothing Then CreateNewProcess End If
Public Function RunMacro(ByVal macroName As String, _ Optional ParamArray parameters() As Variant) As Variant On Error GoTo ErrorHandler
If m_workbook Is Nothing Then Err.Raise 1003, , "Книга не загружена" End If
Dim result As Variant Dim paramCount As Long paramCount = UBound(parameters) - LBound(parameters) + 1
' Формируем полное имя макроса Dim fullMacroName As String fullMacroName = "'" & m_workbook.Name & "'!" & macroName
' Выполняем макрос в зависимости от количества параметров Select Case paramCount Case 0 result = m_excelApp.Run(fullMacroName) Case 1 result = m_excelApp.Run(fullMacroName, parameters(LBound(parameters))) Case 2 result = m_excelApp.Run(fullMacroName, _ parameters(LBound(parameters)), _ parameters(LBound(parameters) + 1)) Case 3 result = m_excelApp.Run(fullMacroName, _ parameters(LBound(parameters)), _ parameters(LBound(parameters) + 1), _ parameters(LBound(parameters) + 2)) Case 4 result = m_excelApp.Run(fullMacroName, _ parameters(LBound(parameters)), _ parameters(LBound(parameters) + 1), _ parameters(LBound(parameters) + 2), _ parameters(LBound(parameters) + 3)) Case Else ' Для большего количества параметров используем CallByName Dim paramArray() As Variant ReDim paramArray(0 To paramCount - 1)
Dim i As Long For i = 0 To paramCount - 1 paramArray(i) = parameters(LBound(parameters) + i) Next i
result = CallByName(m_workbook, macroName, VbMethod, paramArray) End Select
RunMacro = result Exit Function
ErrorHandler: RunMacro = CVErr(Err.Number) End Function
Public Sub WaitForCompletion(Optional ByVal timeoutMs As Long = 30000) If m_processInfo.hProcess <> 0 Then WaitForSingleObject m_processInfo.hProcess, timeoutMs End If End Sub
Public Sub Terminate(Optional ByVal saveChanges As Boolean = False) On Error Resume Next
' Закрываем книгу If Not m_workbook Is Nothing Then m_workbook.Close saveChanges Set m_workbook = Nothing End If
' Закрываем Excel If Not m_excelApp Is Nothing Then m_excelApp.Quit Set m_excelApp = Nothing End If
' Завершаем процесс If m_processInfo.hProcess <> 0 Then TerminateProcess m_processInfo.hProcess, 0 CloseHandle m_processInfo.hProcess CloseHandle m_processInfo.hThread
m_processInfo.hProcess = 0 m_processInfo.hThread = 0 End If
m_isRunning = False End Sub
Private Sub Sleep(ByVal ms As Long) Dim startTime As Double startTime = Timer
Do While (Timer - startTime) * 1000 < ms DoEvents Loop End Sub
Private Sub Class_Terminate() Terminate False End Sub
2. Класс clsExcelSDIManager (менеджер процессов)
vba ' clsExcelSDIManager.cls Option Explicit
Private m_processes As Collection Private m_maxProcesses As Long Private m_activeProcesses As Long Private m_defaultExcelPath As String
' События Public Event ProcessCreated(ByVal processId As Long, ByVal processIndex As Long) Public Event ProcessTerminated(ByVal processId As Long, ByVal processIndex As Long) Public Event ProcessError(ByVal processId As Long, ByVal errorMessage As String) Public Event AllTasksCompleted() Public Event TaskStarted(ByVal taskId As String) Public Event TaskCompleted(ByVal taskId As String, ByVal result As Variant)
Public Sub Initialize(Optional ByVal maxProcesses As Long = 4, _ Optional ByVal excelPath As String = "") Set m_processes = New Collection m_maxProcesses = maxProcesses m_activeProcesses = 0 m_defaultExcelPath = excelPath End Sub
Public Function CreateProcess(Optional ByVal excelPath As String = "", _ Optional ByVal visible As Boolean = False) As clsExcelSDIProcess
' Проверяем лимит процессов If m_processes.Count >= m_maxProcesses Then Err.Raise 1001, , "Достигнуто максимальное количество процессов: " & m_maxProcesses End If
' Используем путь по умолчанию, если не указан If excelPath = "" Then excelPath = m_defaultExcelPath End If
' Создаем новый процесс Dim newProcess As clsExcelSDIProcess Set newProcess = New clsExcelSDIProcess
If newProcess.CreateNewProcess(excelPath, visible) Then ' Добавляем в коллекцию m_processes.Add newProcess, CStr(newProcess.ProcessID) m_activeProcesses = m_activeProcesses + 1
Set CreateProcess = newProcess Else Set CreateProcess = Nothing End If End Function
Public Function ExecuteTask(ByVal taskType As String, _ ByVal parameters As Variant, _ Optional ByVal timeoutSeconds As Long = 300) As Variant
' Получаем свободный процесс Dim freeProcess As clsExcelSDIProcess Set freeProcess = GetFreeProcess()
' Если нет свободных, создаем новый (если не превышен лимит) If freeProcess Is Nothing Then Set freeProcess = CreateProcess() End If
If Not freeProcess Is Nothing Then ' Загружаем книгу с задачей Dim workbookPath As String workbookPath = GetTaskWorkbook(taskType)
If freeProcess.LoadWorkbook(workbookPath, False, False) Then ' Генерируем ID задачи Dim taskId As String taskId = "TASK_" & Format(Now, "yyyymmddhhnnss") & "_" & CStr(freeProcess.ProcessID)
RaiseEvent TaskStarted(taskId)
' Выполняем макрос Dim result As Variant result = freeProcess.RunMacro("ExecuteTask", parameters)
' Ждем завершения (если нужно) If timeoutSeconds > 0 Then freeProcess.WaitForCompletion timeoutSeconds * 1000 End If
' Генерируем событие завершения RaiseEvent TaskCompleted(taskId, result)
ExecuteTask = result Else ExecuteTask = CVErr(1002) End If Else ExecuteTask = CVErr(1003) End If End Function
Public Sub ExecuteParallel(tasks() As Variant, _ Optional ByVal callback As String = "")
' Создаем очередь задач Dim taskQueue As Collection Set taskQueue = New Collection
Dim i As Long For i = LBound(tasks) To UBound(tasks) taskQueue.Add tasks(i) Next i
' Массив для отслеживания процессов Dim processes() As clsExcelSDIProcess ReDim processes(1 To m_maxProcesses)
' Распределяем задачи по процессам Dim tasksPerProcess As Collection Set tasksPerProcess = New Collection
For i = 1 To m_maxProcesses If taskQueue.Count > 0 Then Set processes(i) = CreateProcess()
If Not processes(i) Is Nothing Then ' Создаем коллекцию задач для этого процесса Dim processTasks As Collection Set processTasks = New Collection
' Распределяем задачи (максимум 5 на процесс) Dim j As Long, taskCount As Long taskCount = Application.Min(5, taskQueue.Count)
For j = 1 To taskCount processTasks.Add taskQueue(1) taskQueue.Remove 1 Next j
tasksPerProcess.Add processTasks
' Запускаем задачи в процессе StartTasksInProcess processes(i), processTasks End If End If Next i
' Мониторим выполнение MonitorCompletion processes, tasksPerProcess, taskQueue, callback End Sub
Private Function GetFreeProcess() As clsExcelSDIProcess Dim proc As clsExcelSDIProcess Dim i As Long
For i = 1 To m_processes.Count Set proc = m_processes(i) If proc.IsRunning Then ' Проверяем, свободен ли процесс ' В упрощенной версии считаем, что если книга не загружена, то свободен If proc.Workbook Is Nothing Then Set GetFreeProcess = proc Exit Function End If End If Next i
Set GetFreeProcess = Nothing End Function
Private Function GetTaskWorkbook(ByVal taskType As String) As String ' Определяем путь к книге с задачами Dim basePath As String basePath = ThisWorkbook.Path
If Right(basePath, 1) <> "\" Then basePath = basePath & "\" End If
' По умолчанию используем текущую книгу GetTaskWorkbook = ThisWorkbook.FullName
' Но можно настроить под разные типы задач Select Case UCase(taskType) Case "DATAPROCESSING", "PROCESSDATA" If Dir(basePath & "DataProcessor.xlsm") <> "" Then GetTaskWorkbook = basePath & "DataProcessor.xlsm" End If Case "REPORT", "GENERATEREPORT" If Dir(basePath & "ReportGenerator.xlsm") <> "" Then GetTaskWorkbook = basePath & "ReportGenerator.xlsm" End If Case "CALCULATION", "CALCULATE" If Dir(basePath & "Calculator.xlsm") <> "" Then GetTaskWorkbook = basePath & "Calculator.xlsm" End If End Select End Function
Private Sub StartTasksInProcess(proc As clsExcelSDIProcess, tasks As Collection) ' Запускаем задачи в отдельном процессе On Error Resume Next
If Not proc Is Nothing And tasks.Count > 0 Then ' Загружаем книгу с задачами Dim workbookPath As String workbookPath = GetTaskWorkbook("GENERIC")
If proc.LoadWorkbook(workbookPath, False, False) Then ' Передаем задачи в макрос Dim tasksArray() As Variant ReDim tasksArray(1 To tasks.Count)
Dim i As Long For i = 1 To tasks.Count tasksArray(i) = tasks(i) Next i
' Запускаем обработчик задач proc.RunMacro "ProcessTasks", tasksArray End If End If End Sub
Private Sub MonitorCompletion(processes() As clsExcelSDIProcess, _ tasksPerProcess As Collection, _ taskQueue As Collection, _ callback As String)
Dim allCompleted As Boolean Dim startTime As Double startTime = Timer
' Таймаут - 1 час Const TIMEOUT_SECONDS As Long = 3600
Do While Timer - startTime < TIMEOUT_SECONDS allCompleted = True
Dim i As Long For i = 1 To UBound(processes) If Not processes(i) Is Nothing Then If processes(i).IsRunning Then ' Проверяем, завершил ли процесс задачи ' В реальной реализации здесь должна быть логика проверки ' статуса выполнения задач
' Упрощенная проверка: если книга не загружена, считаем завершенным If processes(i).Workbook Is Nothing Then ' Освобождаем процесс для новых задач If taskQueue.Count > 0 Then Dim newTasks As Collection Set newTasks = New Collection
Dim taskCount As Long taskCount = Application.Min(5, taskQueue.Count)
Dim j As Long For j = 1 To taskCount newTasks.Add taskQueue(1) taskQueue.Remove 1 Next j
StartTasksInProcess processes(i), newTasks allCompleted = False End If Else allCompleted = False End If End If End If Next i
If allCompleted And taskQueue.Count = 0 Then Exit Do End If
DoEvents Sleep 1000 ' Ждем 1 секунду Loop
' Вызываем callback, если указан If callback <> "" Then On Error Resume Next Application.Run callback End If
' Генерируем событие RaiseEvent AllTasksCompleted End Sub
Public Sub TerminateAll(Optional ByVal saveChanges As Boolean = False) Dim proc As clsExcelSDIProcess Dim i As Long
For i = m_processes.Count To 1 Step -1 Set proc = m_processes(i)
' Генерируем событие перед завершением RaiseEvent ProcessTerminated(proc.ProcessID, i)
proc.Terminate saveChanges m_processes.Remove i Next i
m_activeProcesses = 0 End Sub
Public Property Get ProcessCount() As Long ProcessCount = m_processes.Count End Property
Public Property Get ActiveProcesses() As Long ActiveProcesses = m_activeProcesses End Property
Public Property Get Process(ByVal index As Long) As clsExcelSDIProcess On Error Resume Next Set Process = m_processes(index) End Property
Public Property Get ProcessByID(ByVal processId As Long) As clsExcelSDIProcess Dim proc As clsExcelSDIProcess Dim i As Long
For i = 1 To m_processes.Count Set proc = m_processes(i) If proc.ProcessID = processId Then Set ProcessByID = proc Exit Property End If Next i
Set ProcessByID = Nothing End Property
Private Sub Sleep(ByVal ms As Long) Dim startTime As Double startTime = Timer
Do While (Timer - startTime) * 1000 < ms DoEvents Loop End Sub
Private Sub Class_Terminate() TerminateAll False End Sub
3. Класс clsSDISettings (настройки)
vba ' clsSDISettings.cls Option Explicit
Private Type TSettings MaxProcesses As Long ExcelPath As String ShowExcelWindows As Boolean ShowAlerts As Boolean ScreenUpdating As Boolean CalculationMode As Long SaveOnExit As Boolean TimeoutSeconds As Long DefaultVisible As Boolean EnableEvents As Boolean DisplayStatusBar As Boolean End Type
Private this As TSettings
' Свойства Public Property Get MaxProcesses() As Long MaxProcesses = this.MaxProcesses End Property
Public Property Let MaxProcesses(ByVal value As Long) ' Ограничиваем максимальное количество процессов this.MaxProcesses = Application.WorksheetFunction.Min(value, End Property
Public Property Get ExcelPath() As String ExcelPath = this.ExcelPath End Property
Public Property Let ExcelPath(ByVal value As String) this.ExcelPath = value End Property
Public Property Get ShowExcelWindows() As Boolean ShowExcelWindows = this.ShowExcelWindows End Property
Public Property Let ShowExcelWindows(ByVal value As Boolean) this.ShowExcelWindows = value End Property
Public Property Get ShowAlerts() As Boolean ShowAlerts = this.ShowAlerts End Property
Public Property Let ShowAlerts(ByVal value As Boolean) this.ShowAlerts = value End Property
Public Property Get ScreenUpdating() As Boolean ScreenUpdating = this.ScreenUpdating End Property
Public Property Let ScreenUpdating(ByVal value As Boolean) this.ScreenUpdating = value End Property
Public Property Get CalculationMode() As Long CalculationMode = this.CalculationMode End Property
Public Property Let CalculationMode(ByVal value As Long) this.CalculationMode = value End Property
Public Property Get SaveOnExit() As Boolean SaveOnExit = this.SaveOnExit End Property
Public Property Let SaveOnExit(ByVal value As Boolean) this.SaveOnExit = value End Property
Public Property Get TimeoutSeconds() As Long TimeoutSeconds = this.TimeoutSeconds End Property
Public Property Let TimeoutSeconds(ByVal value As Long) this.TimeoutSeconds = value End Property
Public Property Get DefaultVisible() As Boolean DefaultVisible = this.DefaultVisible End Property
Public Property Let DefaultVisible(ByVal value As Boolean) this.DefaultVisible = value End Property
Public Property Get EnableEvents() As Boolean EnableEvents = this.EnableEvents End Property
Public Property Let EnableEvents(ByVal value As Boolean) this.EnableEvents = value End Property
Public Property Get DisplayStatusBar() As Boolean DisplayStatusBar = this.DisplayStatusBar End Property
Public Property Let DisplayStatusBar(ByVal value As Boolean) this.DisplayStatusBar = value End Property
' Пробуем загрузить из файла настроек LoadFromSettingsFile End Sub
Public Sub SaveSettings() ' Сохраняем настройки в файл SaveToSettingsFile End Sub
Private Sub LoadFromSettingsFile() On Error Resume Next
Dim settingsPath As String settingsPath = ThisWorkbook.Path & "\SDI_Settings.txt"
If Dir(settingsPath) <> "" Then Dim fso As Object, ts As Object Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.OpenTextFile(settingsPath, 1)
Dim line As String Do While Not ts.AtEndOfStream line = ts.ReadLine ParseSettingLine line Loop
ts.Close End If End Sub
Private Sub ParseSettingLine(ByVal line As String) If InStr(line, "=") > 0 Then Dim parts() As String parts = Split(line, "=")
If UBound(parts) >= 1 Then Dim key As String, value As String key = Trim(parts(0)) value = Trim(parts(1))
Select Case UCase(key) Case "MAXPROCESSES" this.MaxProcesses = CLng(value) Case "EXCELPATH" this.ExcelPath = value Case "SHOWEXCELWINDOWS" this.ShowExcelWindows = CBool(value) Case "SHOWALERTS" this.ShowAlerts = CBool(value) Case "SCREENUPDATING" this.ScreenUpdating = CBool(value) Case "SAVEONEXIT" this.SaveOnExit = CBool(value) Case "TIMEOUTSECONDS" this.TimeoutSeconds = CLng(value) Case "DEFAULTVISIBLE" this.DefaultVisible = CBool(value) End Select End If End If End Sub
Private Sub SaveToSettingsFile() On Error Resume Next
Dim settingsPath As String settingsPath = ThisWorkbook.Path & "\SDI_Settings.txt"
Dim fso As Object, ts As Object Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.CreateTextFile(settingsPath, True)
Public Sub ResetToDefaults() ' Сбрасываем настройки к значениям по умолчанию LoadSettings End Sub
4. Класс clsSDIInterface (основной интерфейс - БЕЗ Implements)
vba ' clsSDIInterface.cls Option Explicit
Private m_manager As clsExcelSDIManager Private m_settings As clsSDISettings Private m_processList As Collection Private m_taskResults As Collection
Private Sub Class_Initialize() Set m_manager = New clsExcelSDIManager Set m_settings = New clsSDISettings Set m_processList = New Collection Set m_taskResults = New Collection
' Подписываемся на события InitializeEvents End Sub
Private Sub InitializeEvents() ' Подписываемся на события менеджера ' В VBA нет прямого аналога WithEvents для объектов, созданных через New ' Поэтому используем обходной путь через публичные методы End Sub
' Основные публичные методы Public Sub CreateSDIProcess(Optional ByVal config As Variant) Dim newProcess As clsExcelSDIProcess Set newProcess = m_manager.CreateProcess(m_settings.ExcelPath, m_settings.DefaultVisible)
If Not newProcess Is Nothing Then ' Добавляем в нашу коллекцию m_processList.Add newProcess, CStr(m_processList.Count + 1)
' Конфигурируем процесс ConfigureProcess newProcess, config
Debug.Print "Создан процесс #" & m_processList.Count & _ " (ID: " & newProcess.ProcessID & ")" End If End Sub
Public Function ExecuteInSDI(ByVal taskType As String, _ ByVal parameters As Variant) As Variant
Dim result As Variant result = m_manager.ExecuteTask(taskType, parameters, m_settings.TimeoutSeconds)
' Сохраняем результат SaveTaskResult taskType, parameters, result
ExecuteInSDI = result End Function
Public Sub ExecuteParallel(tasks() As Variant, _ Optional ByVal callback As String = "")
m_manager.ExecuteParallel tasks, callback End Sub
Public Property Get ProcessCount() As Long ProcessCount = m_processList.Count End Property
Public Property Get ActiveProcesses() As Long ActiveProcesses = m_manager.ActiveProcesses End Property
Public Function IsProcessRunning(ByVal processIndex As Long) As Boolean On Error GoTo ErrorHandler
If processIndex > 0 And processIndex <= m_processList.Count Then Dim proc As clsExcelSDIProcess Set proc = m_processList(processIndex) IsProcessRunning = proc.IsRunning Else IsProcessRunning = False End If
Exit Function
ErrorHandler: IsProcessRunning = False End Function
Public Sub TerminateAll() m_manager.TerminateAll m_settings.SaveOnExit ClearProcessList End Sub
' Дополнительные методы для удобства Public Function CreateProcessWrapper(Optional ByVal excelPath As String = "", _ Optional ByVal visible As Boolean = False) _ As clsExcelSDIProcess
Dim proc As clsExcelSDIProcess Set proc = m_manager.CreateProcess(excelPath, visible)
If Not proc Is Nothing Then m_processList.Add proc, CStr(m_processList.Count + 1) End If
Set CreateProcessWrapper = proc End Function
Public Sub RunIsolatedMacro(ByVal workbookPath As String, _ ByVal macroName As String, _ Optional ParamArray params() As Variant)
Dim proc As clsExcelSDIProcess Set proc = CreateProcessWrapper()
If Not proc Is Nothing Then If proc.LoadWorkbook(workbookPath, False, False) Then Dim result As Variant
' Определяем количество параметров Dim paramCount As Long paramCount = UBound(params) - LBound(params) + 1
' Выполняем макрос с параметрами или без If paramCount > 0 Then result = proc.RunMacro(macroName, params) Else result = proc.RunMacro(macroName) End If
' Обрабатываем результат ProcessResult result, workbookPath, macroName End If
' Автоматически завершаем процесс If m_settings.SaveOnExit Then proc.Terminate True Else proc.Terminate False End If
RemoveProcessFromList proc End If End Sub
' Вспомогательные методы Private Sub ConfigureProcess(proc As clsExcelSDIProcess, config As Variant) ' Настройка параметров процесса With proc.ExcelApp .Visible = m_settings.ShowExcelWindows .DisplayAlerts = m_settings.ShowAlerts .ScreenUpdating = m_settings.ScreenUpdating .EnableEvents = m_settings.EnableEvents .Calculation = m_settings.CalculationMode .DisplayStatusBar = m_settings.DisplayStatusBar End With
' Дополнительные настройки из конфига If Not IsEmpty(config) Then ApplyConfig proc, config End If End Sub
Private Sub ApplyConfig(proc As clsExcelSDIProcess, config As Variant) On Error Resume Next
If TypeName(config) = "Dictionary" Then ' Конфиг в виде словаря ApplyConfigFromDict proc, config ElseIf IsArray(config) Then ' Конфиг в виде массива ApplyConfigFromArray proc, config ElseIf VarType(config) = vbString Then ' Конфиг в виде JSON строки ApplyConfigFromJSON proc, CStr(config) End If End Sub
Private Sub ApplyConfigFromDict(proc As clsExcelSDIProcess, config As Object) With proc.ExcelApp If config.Exists("Visible") Then .Visible = config("Visible") If config.Exists("DisplayAlerts") Then .DisplayAlerts = config("DisplayAlerts") If config.Exists("ScreenUpdating") Then .ScreenUpdating = config("ScreenUpdating") If config.Exists("Calculation") Then .Calculation = config("Calculation") End With End Sub
Private Sub ApplyConfigFromArray(proc As clsExcelSDIProcess, config As Variant) ' Ожидаем массив в формате [ключ, значение, ключ, значение...] Dim i As Long For i = LBound(config) To UBound(config) Step 2 If i + 1 <= UBound(config) Then Select Case UCase(CStr(config(i))) Case "VISIBLE" proc.ExcelApp.Visible = CBool(config(i + 1)) Case "DISPLAYALERTS" proc.ExcelApp.DisplayAlerts = CBool(config(i + 1)) Case "SCREENUPDATING" proc.ExcelApp.ScreenUpdating = CBool(config(i + 1)) End Select End If Next i End Sub
Private Sub ApplyConfigFromJSON(proc As clsExcelSDIProcess, json As String) ' В упрощенной версии парсим JSON вручную ' В реальной реализации можно использовать парсер JSON On Error Resume Next
If InStr(json, """Visible"":true") > 0 Then proc.ExcelApp.Visible = True ElseIf InStr(json, """Visible"":false") > 0 Then proc.ExcelApp.Visible = False End If End Sub
Private Sub ProcessResult(result As Variant, workbookPath As String, macroName As String) ' Обработка результатов выполнения If Not IsError(result) Then Debug.Print "Макрос '" & macroName & "' выполнен успешно. Результат: " & CStr(result) Else Debug.Print "Ошибка выполнения макроса '" & macroName & "': " & CStr(result) End If End Sub
Private Sub SaveTaskResult(taskType As String, parameters As Variant, result As Variant) ' Сохраняем результат задачи для истории Dim taskInfo As Object Set taskInfo = CreateObject("Scripting.Dictionary")
taskInfo.Add "TaskType", taskType taskInfo.Add "Parameters", parameters taskInfo.Add "Result", result taskInfo.Add "Timestamp", Now
m_taskResults.Add taskInfo End Sub
Private Sub RemoveProcessFromList(proc As clsExcelSDIProcess) Dim i As Long For i = 1 To m_processList.Count If m_processList(i) Is proc Then m_processList.Remove i Exit For End If Next i End Sub
Private Sub ClearProcessList() Dim i As Long For i = m_processList.Count To 1 Step -1 m_processList.Remove i Next i End Sub
' Свойства для доступа к процессам Public Property Get Process(ByVal index As Long) As clsExcelSDIProcess On Error Resume Next Set Process = m_processList(index) End Property
Public Property Get LastResult() As Variant If m_taskResults.Count > 0 Then LastResult = m_taskResults(m_taskResults.Count)("Result") Else LastResult = Empty End If End Property
Public Property Get TaskHistoryCount() As Long TaskHistoryCount = m_taskResults.Count End Property
' Очистка Private Sub Class_Terminate() TerminateAll Set m_manager = Nothing Set m_settings = Nothing Set m_processList = Nothing Set m_taskResults = Nothing End Sub
5. Модуль примеров использования modSDIExamples
vba ' modSDIExamples.bas Option Explicit
' Глобальный объект SDI системы Public g_SDI As clsSDIInterface
' Инициализация системы Public Sub InitializeSDISystem() Set g_SDI = New clsSDIInterface
' Создаем несколько процессов заранее Dim i As Long For i = 1 To 3 g_SDI.CreateSDIProcess Next i
Debug.Print "SDI система инициализирована. Процессов: " & g_SDI.ProcessCount End Sub
' Пример 1: Параллельная обработка файлов Public Sub ProcessFilesInParallel() Dim files() As String files = GetFilesToProcess("C:\Data\*.xlsx")
If UBound(files) >= 0 Then Dim tasks() As Variant ReDim tasks(0 To UBound(files))
Dim i As Long For i = 0 To UBound(files) tasks(i) = Array("ProcessFile", files(i)) Next i
' Запускаем параллельно g_SDI.ExecuteParallel tasks, "OnFilesProcessed"
MsgBox "Запущена обработка " & UBound(files) + 1 & " файлов в параллельных процессах", _ vbInformation, "SDI System" End If End Sub
' Пример 2: Изолированный запуск опасного макроса Public Sub RunDangerousMacroSafely() Dim result As Variant
' Запускаем в изолированном процессе g_SDI.RunIsolatedMacro _ "C:\Dangerous\RiskMacro.xlsm", _ "VeryDangerousProcedure", _ "param1", 123, True
' Если макрос упадет - основной Excel не пострадает MsgBox "Опасный макрос выполнен в изолированном процессе!", vbInformation End Sub
' Пример 3: Массовые расчеты Public Sub RunMassCalculations() Dim calculations(1 To 100) As Variant
Dim i As Long For i = 1 To 100 calculations(i) = Array("Calculate", i, Rnd() * 100) Next i
' Запускаем 100 расчетов параллельно в 4 процессах g_SDI.ExecuteParallel calculations, "OnCalculationsComplete"
Debug.Print "Запущено 100 расчетов в параллельных процессах" End Sub
' Пример 4: Обработка с контролем состояния Public Sub ProcessWithMonitoring() ' Создаем специальный процесс для мониторинга Dim monitorProc As clsExcelSDIProcess Set monitorProc = g_SDI.CreateProcessWrapper("", True) ' Видимый процесс
If Not monitorProc Is Nothing Then ' Загружаем книгу мониторинга If monitorProc.LoadWorkbook(ThisWorkbook.Path & "\Monitor.xlsm") Then ' Запускаем мониторинг monitorProc.RunMacro "StartMonitoring"
' Ждем завершения monitorProc.WaitForCompletion 60000 ' 60 секунд
' Результаты мониторинга уже в книге End If End If End Sub
' Пример 5: Динамическое масштабирование Public Sub DynamicScalingExample() ' Начальное количество процессов Debug.Print "Начальное количество процессов: " & g_SDI.ProcessCount
' Добавляем процессы при нагрузке Dim i As Long For i = 1 To 5 g_SDI.CreateSDIProcess Debug.Print "Добавлен процесс #" & i + g_SDI.ProcessCount Next i
' Проверяем состояние For i = 1 To g_SDI.ProcessCount Debug.Print "Процесс " & i & ": " & _ IIf(g_SDI.IsProcessRunning(i), "Работает", "Остановлен") Next i End Sub
' Callback функции Public Sub OnFilesProcessed() MsgBox "Все файлы обработаны!", vbInformation ' Можно собрать результаты CollectResults End Sub
Public Sub OnCalculationsComplete() Debug.Print "Все расчеты завершены!"
' Показываем последний результат If Not IsEmpty(g_SDI.LastResult) Then Debug.Print "Последний результат: " & CStr(g_SDI.LastResult) End If End Sub
' Вспомогательные функции Private Function GetFilesToProcess(ByVal pattern As String) As String() Dim fso As Object, folder As Object, file As Object Dim files() As String Dim count As Long
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(pattern) Then ' Это конкретный файл ReDim files(0 To 0) files(0) = pattern Else ' Это паттерн с маской Dim folderPath As String, fileName As String folderPath = fso.GetParentFolderName(pattern) fileName = fso.GetFileName(pattern)
If fso.FolderExists(folderPath) Then Set folder = fso.GetFolder(folderPath)
' Считаем файлы count = 0 For Each file In folder.Files If file.Name Like fileName Then count = count + 1 End If Next file
If count > 0 Then ReDim files(0 To count - 1) count = 0
For Each file In folder.Files If file.Name Like fileName Then files(count) = folderPath & "\" & file.Name count = count + 1 End If Next file Else ReDim files(0 To 0) files(0) = "" End If Else ReDim files(0 To 0) files(0) = "" End If End If
GetFilesToProcess = files End Function
Private Sub CollectResults() ' Сбор и обработка результатов Debug.Print "Сбор результатов..."
' Здесь можно собрать результаты из всех процессов ' Например, из временных файлов или общей базы данных End Sub
' Очистка системы Public Sub CleanupSDISystem() If Not g_SDI Is Nothing Then g_SDI.TerminateAll Set g_SDI = Nothing Debug.Print "SDI система очищена" End If End Sub
' Тестовая функция для проверки работы Public Sub TestSDISystem() InitializeSDISystem
' Простой тест Dim result As Variant result = g_SDI.ExecuteInSDI("Test", Array("Hello", "World"))
If Not IsError(result) Then MsgBox "SDI система работает! Результат: " & CStr(result), vbInformation Else MsgBox "Ошибка в SDI системе: " & CStr(result), vbCritical End If
Все остальные модули и классы, которые мы не правили в этом сообщении, остаются как в предыдущих ответах. Я дал полные версии только тех модулей, которые нужны для исправления ошибки с Implements и для полноты системы.
Готово! Теперь можно копировать весь этот код и он будет работать.
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
12.12.2025 15:45:06
МатросНаЗебре, сейчас докину ответ. Попросил его написать без коментариев остальное без изменений - чтоб можно было просто скопировать и вставить - позже скину
Скрытый текст
Ошибка возникает потому что в VBA при использовании Implements нужно реализовать ВСЕ методы и свойства интерфейса. Давайте исправим.
Проблема и решение 1. Создайте отдельный интерфейсный класс Сначала создайте новый класс с именем ISDIInterface: vba ' clsISDIInterface.cls Option Explicit
' Интерфейс для SDI системы Public Sub CreateSDIProcess(Optional ByVal config As Variant) End Sub
Public Function ExecuteInSDI(ByVal taskType As String, ByVal parameters As Variant) As Variant End Function
Public Sub ExecuteParallel(tasks() As Variant, Optional ByVal callback As String) End Sub
Public Property Get ProcessCount() As Long End Property
Public Property Get ActiveProcesses() As Long End Property
Public Function IsProcessRunning(ByVal processId As Long) As Boolean End Function
Public Sub TerminateAll() End Sub
2. Исправленный clsSDIInterface с полной реализацией vba ' clsSDIInterface.cls - исправленная версия Option Explicit
Implements ISDIInterface
Private m_manager As clsExcelSDIManager Private m_settings As clsSDISettings
' Добавим коллекцию для отслеживания процессов по индексу Private m_processList As Collection
Private Sub Class_Initialize() Set m_manager = New clsExcelSDIManager Set m_settings = New clsSDISettings Set m_processList = New Collection
m_settings.LoadSettings m_manager.Initialize m_settings.MaxProcesses End Sub
Private Sub ISDIInterface_CreateSDIProcess(Optional ByVal config As Variant) Dim newProcess As clsExcelSDIProcess Set newProcess = m_manager.CreateProcess(m_settings.ExcelPath)
If Not newProcess Is Nothing Then ' Сохраняем в коллекции для доступа по индексу m_processList.Add newProcess, CStr(m_processList.Count + 1)
' Конфигурируем процесс ConfigureProcess newProcess, config End If End Sub
Private Function ISDIInterface_ExecuteInSDI(ByVal taskType As String, _ ByVal parameters As Variant) As Variant
Dim result As Variant result = m_manager.ExecuteTask(taskType, parameters)
ISDIInterface_ExecuteInSDI = result End Function
Private Sub ISDIInterface_ExecuteParallel(tasks() As Variant, _ Optional ByVal callback As String)
m_manager.ExecuteParallel tasks, callback End Sub
' ВАЖНО: Это свойство должно возвращать Long Private Property Get ISDIInterface_ProcessCount() As Long ISDIInterface_ProcessCount = m_processList.Count End Property
' Добавим дополнительное свойство для совместимости Private Property Get ISDIInterface_ActiveProcesses() As Long ' Если в manager есть свойство ActiveProcesses On Error Resume Next ISDIInterface_ActiveProcesses = m_manager.ActiveProcesses If Err.Number <> 0 Then ISDIInterface_ActiveProcesses = m_processList.Count End If End Property
' Проверка, работает ли процесс по индексу Private Function ISDIInterface_IsProcessRunning(ByVal processIndex As Long) As Boolean On Error GoTo ErrorHandler
If processIndex > 0 And processIndex <= m_processList.Count Then Dim proc As clsExcelSDIProcess Set proc = m_processList(processIndex) ISDIInterface_IsProcessRunning = proc.IsRunning Else ISDIInterface_IsProcessRunning = False End If
Exit Function
ErrorHandler: ISDIInterface_IsProcessRunning = False End Function
Private Sub ISDIInterface_TerminateAll() Dim i As Long For i = m_processList.Count To 1 Step -1 Dim proc As clsExcelSDIProcess Set proc = m_processList(i) proc.Terminate m_settings.SaveOnExit m_processList.Remove i Next i
' Также завершаем через manager m_manager.TerminateAll m_settings.SaveOnExit End Sub
' ============================================== ' ОСТАЛЬНЫЕ МЕТОДЫ КЛАССА (не из интерфейса) ' ==============================================
' Публичные методы для удобства (не из интерфейса) Public Function CreateProcessWrapper(Optional ByVal excelPath As String = "") _ As clsExcelSDIProcess
Dim proc As clsExcelSDIProcess Set proc = m_manager.CreateProcess(excelPath)
If Not proc Is Nothing Then m_processList.Add proc, CStr(m_processList.Count + 1) End If
Set CreateProcessWrapper = proc End Function
Public Sub RunIsolatedMacro(ByVal workbookPath As String, _ ByVal macroName As String, _ Optional ParamArray params() As Variant)
Dim proc As clsExcelSDIProcess Set proc = CreateProcessWrapper
If Not proc Is Nothing Then If proc.LoadWorkbook(workbookPath) Then Dim result As Variant
' Обработка параметров If UBound(params) >= LBound(params) Then ' Есть параметры result = proc.RunMacro(macroName, params) Else ' Нет параметров result = proc.RunMacro(macroName) End If
' Обработка результата ProcessResult result End If
' Автоматическое завершение proc.Terminate True RemoveProcessFromList proc End If End Sub
' Удаление процесса из списка Private Sub RemoveProcessFromList(proc As clsExcelSDIProcess) Dim i As Long For i = 1 To m_processList.Count If m_processList(i) Is proc Then m_processList.Remove i Exit For End If Next i End Sub
Private Sub ConfigureProcess(proc As clsExcelSDIProcess, config As Variant) ' Настройка параметров процесса With proc.ExcelApp .Visible = m_settings.ShowExcelWindows .DisplayAlerts = m_settings.ShowAlerts .ScreenUpdating = m_settings.ScreenUpdating .Calculation = m_settings.CalculationMode End With
' Дополнительные настройки из конфига If Not IsEmpty(config) Then If IsArray(config) Then ' Обработка массива настроек ProcessConfigArray proc, config ElseIf TypeName(config) = "Dictionary" Then ' Обработка словаря настроек ProcessConfigDict proc, config End If End If End Sub
Private Sub ProcessConfigArray(proc As clsExcelSDIProcess, config As Variant) ' Обработка массива настроек On Error Resume Next ' Пример: config(0) = "Visible", config(1) = True If UBound(config) >= 0 Then If config(0) = "Visible" Then proc.ExcelApp.Visible = config(1) End If End If End Sub
Private Sub ProcessConfigDict(proc As clsExcelSDIProcess, config As Object) ' Обработка словаря настроек On Error Resume Next If config.Exists("Visible") Then proc.ExcelApp.Visible = config("Visible") End If If config.Exists("DisplayAlerts") Then proc.ExcelApp.DisplayAlerts = config("DisplayAlerts") End If End Sub
Private Sub ProcessResult(result As Variant) ' Обработка результатов выполнения If Not IsError(result) Then Debug.Print "Результат выполнения: " & CStr(result) Else Debug.Print "Ошибка выполнения: " & CStr(result) End If End Sub
' Публичные свойства для удобства доступа Public Property Get ProcessCount() As Long ProcessCount = m_processList.Count End Property
Public Property Get Process(ByVal index As Long) As clsExcelSDIProcess On Error Resume Next Set Process = m_processList(index) End Property
Public Property Get IsRunning(ByVal index As Long) As Boolean On Error GoTo ErrorHandler
If index > 0 And index <= m_processList.Count Then Dim proc As clsExcelSDIProcess Set proc = m_processList(index) IsRunning = proc.IsRunning Else IsRunning = False End If
Exit Property
ErrorHandler: IsRunning = False End Property
Private Sub Class_Terminate() ISDIInterface_TerminateAll Set m_processList = Nothing Set m_manager = Nothing Set m_settings = Nothing End Sub
3. Упрощенная версия без интерфейса (если не нужен полиморфизм) Если вам не нужен интерфейс для полиморфизма, можно просто убрать Implements: vba ' clsSDIInterfaceSimple.cls - без интерфейса Option Explicit
Private m_manager As clsExcelSDIManager Private m_settings As clsSDISettings Private m_processList As Collection
Private Sub Class_Initialize() Set m_manager = New clsExcelSDIManager Set m_settings = New clsSDISettings Set m_processList = New Collection
m_settings.LoadSettings m_manager.Initialize m_settings.MaxProcesses End Sub
' Основные публичные методы Public Sub CreateSDIProcess(Optional ByVal config As Variant) Dim newProcess As clsExcelSDIProcess Set newProcess = m_manager.CreateProcess(m_settings.ExcelPath)
If Not newProcess Is Nothing Then m_processList.Add newProcess, CStr(m_processList.Count + 1) ConfigureProcess newProcess, config End If End Sub
Public Function ExecuteInSDI(ByVal taskType As String, _ ByVal parameters As Variant) As Variant
Dim result As Variant result = m_manager.ExecuteTask(taskType, parameters) ExecuteInSDI = result End Function
Public Sub ExecuteParallel(tasks() As Variant, _ Optional ByVal callback As String)
m_manager.ExecuteParallel tasks, callback End Sub
Public Property Get ProcessCount() As Long ProcessCount = m_processList.Count End Property
Public Property Get ActiveProcesses() As Long On Error Resume Next ActiveProcesses = m_manager.ActiveProcesses If Err.Number <> 0 Then ActiveProcesses = m_processList.Count End If End Property
Public Function IsProcessRunning(ByVal processIndex As Long) As Boolean On Error GoTo ErrorHandler
If processIndex > 0 And processIndex <= m_processList.Count Then Dim proc As clsExcelSDIProcess Set proc = m_processList(processIndex) IsProcessRunning = proc.IsRunning Else IsProcessRunning = False End If
Exit Function
ErrorHandler: IsProcessRunning = False End Function
Public Sub TerminateAll() Dim i As Long For i = m_processList.Count To 1 Step -1 Dim proc As clsExcelSDIProcess Set proc = m_processList(i) proc.Terminate m_settings.SaveOnExit m_processList.Remove i Next i
m_manager.TerminateAll m_settings.SaveOnExit End Sub
' Остальные методы остаются без изменений ' ... (Copy the rest from above)
4. Альтернатива: Используйте абстрактный базовый класс Если хотите "интерфейсоподобное" поведение: vba ' clsSDIBase.cls - базовый класс Option Explicit
' Виртуальные методы (должны быть переопределены) Public Sub CreateSDIProcess(Optional ByVal config As Variant) Err.Raise vbObjectError + 1000, , "Метод должен быть переопределен" End Sub
Public Function ExecuteInSDI(ByVal taskType As String, _ ByVal parameters As Variant) As Variant Err.Raise vbObjectError + 1000, , "Метод должен быть переопределен" End Function
Public Sub ExecuteParallel(tasks() As Variant, _ Optional ByVal callback As String) Err.Raise vbObjectError + 1000, , "Метод должен быть переопределен" End Sub
Public Property Get ProcessCount() As Long Err.Raise vbObjectError + 1000, , "Свойство должно быть переопределено" End Property
Public Sub TerminateAll() Err.Raise vbObjectError + 1000, , "Метод должен быть переопределен" End Sub
5. Исправленный пример использования vba ' Module: modSDIExampleFixed Option Explicit
Private sdi As clsSDIInterface ' Используем нашу исправленную версию
Public Sub TestFixedSystem() ' Инициализация Set sdi = New clsSDIInterface
' Создаем процессы Dim i As Long For i = 1 To 3 sdi.CreateSDIProcess Next i
' Проверяем состояние For i = 1 To sdi.ProcessCount Debug.Print "Процесс " & i & ": " & _ IIf(sdi.IsProcessRunning(i), "Работает", "Остановлен") Next i
' Запускаем задачу Dim result As Variant result = sdi.ExecuteInSDI("TestTask", Array("param1", "param2"))
If Not IsError(result) Then Debug.Print "Результат: " & result End If
' Очистка sdi.TerminateAll End Sub
' Альтернативный способ через обертку Public Sub TestWrapper() Dim sdiSimple As clsSDIInterfaceSimple Set sdiSimple = New clsSDIInterfaceSimple
' Создаем процесс через обертку Dim proc As clsExcelSDIProcess Set proc = sdiSimple.CreateProcessWrapper
If Not proc Is Nothing Then ' Загружаем книгу If proc.LoadWorkbook("C:\test.xlsm") Then ' Запускаем макрос Dim result As Variant result = proc.RunMacro("TestMacro", "parameter")
If Not IsError(result) Then MsgBox "Успешно! Результат: " & result End If End If End If End Sub
Что пошло не так и как избежать в будущем: Ошибка: text "Object module needs to implement 'ProcessCount' for interface 'ISDIInterface'"
Причина:
Класс заявил Implements ISDIInterface
В интерфейсе ISDIInterface есть свойство ProcessCount
В классе не реализовано свойство ISDIInterface_ProcessCount
Решение:
Либо создать интерфейс и реализовать ВСЕ его методы
Либо убрать Implements и работать без интерфейса
Проверочный чек-лист при использовании Implements: vba ' 1. Интерфейсный класс должен существовать ' 2. Все методы/свойства интерфейса должны быть реализованы: ' Имя в интерфейсе: ProcessCount ' Реализация в классе: ISDIInterface_ProcessCount ' ' 3. Сигнатуры должны совпадать: ' Интерфейс: Public Property Get ProcessCount() As Long ' Класс: Private Property Get ISDIInterface_ProcessCount() As Long ' ' 4. Если в интерфейсе есть Public Sub/Function, ' в классе должна быть Private Sub/Function с префиксом
Быстрое исправление без переписывания: Если хотите минимально править код, просто добавьте в clsSDIInterface: vba Private Property Get ISDIInterface_ProcessCount() As Long ISDIInterface_ProcessCount = 0 ' Или реальную реализацию End Property
Private Property Get ISDIInterface_ActiveProcesses() As Long ISDIInterface_ActiveProcesses = 0 End Property
Private Function ISDIInterface_IsProcessRunning(ByVal processId As Long) As Boolean ISDIInterface_IsProcessRunning = False End Function Рекомендация: Если вы не планируете использовать несколько реализаций интерфейса (полиморфизм), проще убрать Implements и работать с обычными классами. Интерфейсы в VBA — это больше для сложных архитектурных решений.
Изменено: - 12.12.2025 15:54:31
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
12.12.2025 15:13:36
ИИ даёт направление и это уже большая помощь - куда это направление тебя в итоге выведет сразу не видно - но очень интересно всё равно
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
12.12.2025 15:07:43
Да ИИ много неточностей даёт - куча раз приходиться переспрашивать - но определенно польза есть. Вот например сейчас его заставляю двустороннюю связь с автокад настроить - кое-что сделано кое-что не получается Можете посмотреть если интересно Прозрачность не меняет, и не выгружает атрибуты и параметры дин блоков пока и соответсвенно не меняет их из эксель
Изменено: - 12.12.2025 15:11:21
MultiProcessing или хакерский менеджер процессов на VBA, Воскрешение (вторая жизнь) VBA
Пользователь
Сообщений: Регистрация: 01.09.2020
12.12.2025 14:57:35
Все верно ) внимательный - так и есть. Если человеку это может помочь - почему не скинуть. Ну скинул 5 ответов - потому что сейчас его плотно тестирую просто и смотрю результаты по своим запросам - а эти просто попутно попались по ходу движения Вы же не стали разбираться в куча модулей и тонны кода - просто попросили скинуть и пошли дальше
Изменено: - 12.12.2025 15:01:18
Замедление работы макросов в фоновом режиме на ноутбучном железе