В общем, пока что только гугл с периодическими отваливаниями =( Если у кого-то есть еще жизнеспособные варианты, будет отлично. Насколько помню, у Николая Павлова надстройка сама понимает какая версия. Кто знает, как это чудо реализовано? Хотелось бы иметь такую же возможность - проверка версии, если есть более новая - скачивает
написал: У вас не файл загружается, а текст с сообщением об ошибке / какой-то HTML кодВот этот скачанный файл размером 2кБ откройте в Блокноте, и посмотрите что там написано.
Ага, вот где собака зарыта... Значит, надо искать обходной вариант гугл диска... Пока что нет представления, где можно разместить файл, чтобы сделать автообновление. VBA может забрать только с прямой ссылки для скачивания, насколько осведомлен... DropBox в России неисправен, Yandex-Disk не дает прямых ссылок, OneDrive теперь тоже нельзя так использовать... Уже начал терять надежду
Вводные: У меня есть 2 надстройки - New One.xlam (- служит для всех макросов) - AutoUpdate.xlam (только для обновления New One.xlam)
Самостоятельно разобраться в автообновлении не смог, поэтому сделал по кнопке.
Как работало: Скачанный гугл диск - автообновление файла New One.xlam на нем из папки Addins (синхронизация папки) - кнопка прожимается у коллеги - отключается надстройка - скачивается файл с гугл диска - добавляется в надстройки - включается. Процесс завершен
Сейчас же происходит очень неприятная история: файл с гугл диска загружается битым. Его вес ~152кб, а загружается через макрос → вес в 2кб. Причины понять не могу.
Скачиваю по ссылке из макроса, вставляя ее в браузер - все нормально вес ~152кб, VBA не ругается. Других способов автообновления собственной надстройки не знаю.
Sub DownloadAndInstallAddInW()
' Your code here to download the latest Add-In version
Dim downloadURL As String
'Application.AddIns("New One").Installed = False
downloadURL = "https://drive.google.com/uc?export=download&id=1-_XQWIJVgMUFU253id1d_dn8PlHfb5X-" ' Replace with the actual download URL
' Specify the local path for saving the downloaded Add-In
Dim localPath As String
localPath = Environ("USERPROFILE") & "\Desktop\New One.xlam" ' Replace with your desired local path
' Download the Add-In
DownloadFileW downloadURL, localPath
'Call Add_AddinW
MsgBox "Надстройка успешно обновлена!"
End Sub
' Function to download a file from a URL
Sub DownloadFileW(url As String, localPath As String)
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
WinHttpReq.Open "GET", url, False
WinHttpReq.Send
If WinHttpReq.Status = 200 Then
Dim oStream As Object
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1
oStream.Write WinHttpReq.ResponseBody
oStream.SaveToFile localPath, 2 ' 1 = no overwrite, 2 = overwrite
oStream.Close
Else
MsgBox "Failed to download the Add-In. Status: " & WinHttpReq.Status
End If
End Sub
Sub Add_AddinW()
If Application.AddIns("New One").Installed = True Then
Application.AddIns("New One").Installed = False
With Application
.AddIns.Add Environ("USERPROFILE") & "\Desktop\New One.xlam", True
End With
End If
If Application.AddIns("New One").Installed = False Then
Application.AddIns("New One").Installed = True
End If
End Sub
В чем может быть причина? Может можно как-то оптимизировать автообновление? Как лечить подобную ситуацию и с чем вообще возникает проблема? Заранее спасибо гуру за советы
написал: Здравствуйте Вы ошибаетесь, что явно указано другое.
Цитата
написал: Можно ещё ускорить по желанию, гуру если что поправят
Цитата
написал: Wadee , добрый вечер.
Хочу высказать каждому из вас огромное спасибо. Вы как нельзя лучше объяснили и продемонстрировали мастерство. Моя скромная благодарность не знает границ. Спасибо каждому из вас еще раз. Сейчас сяду и буду штудировать код символ за символом, чтобы точно разобраться и понять. Низкий поклон!
Чтобы получить результат вычисления - нужен калькулятор. В нашем случае - формула в ячейке. Если мы отберём калькулятор, то вычислять будет нечему. Без VBA только руками Ячейки между собой считаются равными по иерархии. Мы не можем заставить одну руководить другой. Только добавить зависимость. А вот VBA абсолютно все равно на ячейки - для него это чистый холст. Жаль, что задача невыполнима стандартными методами
Не понял описания, если честно. Но вывести положительные и отрицательные суммы по идентификаторам, которые начинаются на 8 сделал. Можно прописать "СУММ" перед формулой динамического массива... Может что-то не так понял
Друзья, всем привет! Недавно начал постигать азы VBA, не кидайте, пожалуйста, сильно камнями. Код у меня не может похвастаться чистотой, да и правильностью работы.
Нужна ваша помощь.
Сама суть: есть 3 столбца на "Лист1". Столбец A - Идентификатор, Столбец B - Дата и время начала смены, Столбец C - Дата и время окончания смены. Нужно построить график присутствия в каждый часовой интервал.
Задача: На втором листе создать график так, чтобы были только уникальные идентификаторы в столбце A, в ячейках справа от них были количества встречающихся значений по часу.
Имеется: Исходная таблица с данными, строка Даты-времени на "Лист2", чтобы понимать в какой интервал каждый идентификатор есть/нет и в каком количестве.
Почему необходимо: Работаю с огромными массивами данных, количество идентификаторов в исходной таблице "Лист1" занимает порядка 200тыс строк, количество столбцов на "Лист2" в разбивке по часам составляет около 2252 столбцов (что эквивалентно 3 месяцам в разбивке по часам). С формулами грузит в районе 4 часов. При работе с выдачей массивов через For - около часа. Хочется максимально ускорить процесс. SQL не обладаю, поэтому пытаюсь через VBA. Изучаю все постепенно.
Что не смог решить сам: почему-то макрос при начале смены в 12:00 вставляет значение в 11:00, хотя явно указано другое.
Файл примера прикрепил. Ничего лишнего. Объем данных оставил минимальным.
Код
Sub Создать_График()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim lastRow1 As Long, lastRow2 As Long
Dim i As Long, j As Long, k As Long
Dim name As String
Dim startDateTime As Date, endDateTime As Date
Dim currentDateTime As Date
Dim hoursDiff As Integer
Dim presenceCount As Integer
Dim nameColumn As Integer
Dim uniqueNames As Collection
' Указываем листы
Set ws1 = ThisWorkbook.Sheets("Лист1")
Set ws2 = ThisWorkbook.Sheets("Лист2")
' Находим последнюю заполненную строку на Листе1 и Листе2
lastRow1 = ws1.Cells(ws1.Rows.count, "B").End(xlUp).Row
lastRow2 = ws2.Cells(ws2.Rows.count, "A").End(xlUp).Row
' Находим последний столбец с именами на Листе2
nameColumn = ws2.Cells(1, ws2.Columns.count).End(xlToLeft).Column
' Инициализируем коллекцию для хранения уникальных имен
Set uniqueNames = New Collection
' Проходим по каждой строке на Листе1
For i = 2 To lastRow1
' Получаем имя
name = ws1.Cells(i, 1).Value
' Проверяем, является ли имя уникальным
On Error Resume Next
uniqueNames.Add name, CStr(name)
On Error GoTo 0
Next i
' Добавляем уникальные имена на Лист2
For i = 1 To uniqueNames.count
If Application.WorksheetFunction.CountIf(ws2.Range("A:A"), uniqueNames.Item(i)) = 0 Then
ws2.Cells(lastRow2 + i, 1).Value = uniqueNames.Item(i)
End If
Next i
' Проходим по каждой строке в Листе2 (каждому уникальному имени)
For i = 2 To lastRow2 + uniqueNames.count
' Получаем имя
name = ws2.Cells(i, 1).Value
' Проходим по каждой строке на Листе1
For j = 2 To lastRow1
' Проверяем, совпадает ли имя на Листе1 с текущим именем на Листе2
If ws1.Cells(j, 1).Value = name Then
' Получаем дату и время начала и окончания работы
startDateTime = ws1.Cells(j, 2).Value
endDateTime = ws1.Cells(j, 3).Value
' Проходим по каждому часу в промежутке между началом и окончанием работы
For k = 0 To DateDiff("h", startDateTime, endDateTime)
currentDateTime = DateAdd("h", k, startDateTime)
' Подсчитываем присутствие в каждом часе
If currentDateTime >= ws2.Cells(1, 2).Value And currentDateTime <= ws2.Cells(1, ws2.Columns.count).End(xlToLeft).Value Then
hoursDiff = DateDiff("h", ws2.Cells(1, 2).Value, currentDateTime) + 1
presenceCount = ws2.Cells(i, hoursDiff).Value
ws2.Cells(i, hoursDiff).Value = presenceCount + 1
End If
Next k
End If
Next j
Next i
' Форматируем данные на Листе2
ws2.Rows(1).AutoFilter
ws2.Columns.AutoFit
End Sub
Столбец AE на листе 100752. Там формула, которая дает желаемый результат. При этом диапазон исторических данных (откуда и тянется формула) расширяется каждый день/неделю.
Собственно, писал-писал код. Есть исходные данные, есть таблица на листе 100752, которую необходимо заполнить Не выходит и все тут Даже в конце кода если убрать деление на количество (findcount), то все равно либо пишет ЗНАЧ, либо некоторые значения пропускает.
Сама задача такова: заполнить в каждой ячейке среднее по дню недели и времени, в соответствии с номером (в ячейке B3) - это канал связи. Код есть в самом документе, который, естественно, прикладываю.
Где накосячил, что не так сделал - не понимаю. Пытаюсь создать как можно более простую функцию, поскольку дальше будет еще веселее, очень много расчетов в файлах. Документы весят по 100+ мб. Поэтому стараюсь все перегнать в массивы и выводить только результат на лист после просчета в самом VBA. Выручайте, товарищи! Каков будет самый "быстрый способ" реализации этой прелести? Если сможете еще указать на ошибки в коде, то буду дополнительно признателен, поскольку пока только учусь...
Код
Function CustomFilterFunction(dayweekcrit As Variant, timecrit As Double, qcrit As Variant) As Variant
'dayweekcrit As Variant, timecrit As Variant
Dim result As Double
Dim findcount As Long
Dim sumvolume As Double
findcount = 0
sumvolume = 0
'Dim i As Integer
'Dim j As Integer
Dim Volumerange As Range
Dim dayweekrange As Range
Dim timerange As Range
Dim qrange As Range
Dim volumeArray() As Variant
Dim dayweekarray() As Variant
Dim timearray() As Variant
Dim qarray() As Variant
Worksheets("History").Activate
Set Volumerange = Worksheets("History").Range("AL3:AL" & Worksheets("History").Cells(Rows.count, "AL").End(xlUp).Row)
Set dayweekrange = Worksheets("History").Range("AP3:AP" & Worksheets("History").Cells(Rows.count, "AL").End(xlUp).Row)
Set timerange = Worksheets("History").Range("AS3:AS" & Worksheets("History").Cells(Rows.count, "AL").End(xlUp).Row)
Set qrange = Worksheets("History").Range("AK3:AK" & Worksheets("History").Cells(Rows.count, "AK").End(xlUp).Row)
volumeArray() = Volumerange.Value
dayweekarray() = dayweekrange.Value
timearray() = timerange.Value
qarray() = qrange.Value
For i = 1 To Worksheets("History").Cells(Rows.count, "AL").End(xlUp).Row - 2
If qrange.Cells(i).Value = qcrit And dayweekrange.Cells(i).Value = dayweekcrit And timerange.Cells(i).Value = timecrit Then
sumvolume = sumvolume + Volumerange.Cells(i).Value
findcount = findcount + 1
End If
Next
CustomFilterFunction = sumvolume
End Function
Чего только не пробовал, чтобы перенести... Есть огромная формула, которая считает правильно (она находится в ячейке L2). В K2 - тоже самое, только с лямбдой
Суть вопроса: кто может помочь Это волшебство закинуть в функцию. Пробовал через чат с OpenAI GPT - он ругается, когда в массиве столбца B есть нулевое значение, а это обязательно и формула это предусматривает. По сути, хочу придти к итогу: Вставил курсор в ячейку вбил "=какаятотамфункция( массив1, массив 2) и оно считает внутри VBA
Есессно файл с примером и рабочей формулой (не VBA) прикладываю. Если есть кто добрый из старичков, кто если сразу не пошлет с этим, а хотя бы скажет, куда копать и откуда магнитик привезти - сбегаю, посмотрю, прочитаю, изучу. Если же кто-то подкинет код - сократит мне часов 10 разбирательств. Потому что дальше я сам его проштудирую и изучу по наитию
Sub MyMacro()
Worksheets("Sheet1").Activate
Worksheets("Sheet1").Range("E95:AI118").FormulaLocal = "=СУММПРОИЗВ(ЕСЛИОШИБКА(ЕСЛИ(ЛЕВСИМВ(E$20:E$80;5)*1<=$D95;1;0);0)*1;ЕСЛИОШИБКА(ЕСЛИ(ПРАВСИМВ(E$20:E$80;5)*1>$D95;1;0);0)*1)+СУММПРОИЗВ(ЕСЛИОШИБКА(ЕСЛИ(ЛЕВСИМВ(E$20:E$80;5)*1<=$D95;1;0);0)*1;ЕСЛИОШИБКА(ЕСЛИ(ПРАВСИМВ(E$20:E$80;5)*1<$D95;1;0);0)*1;ЕСЛИОШИБКА(ЕСЛИ(ЛЕВСИМВ(E$20:E$80;5)*1>ПРАВСИМВ(E$20:E$80;5)*1;1;0);0)*1)+СУММПРОИЗВ(ЕСЛИОШИБКА(ЕСЛИ(ПРАВСИМВ(D$20:D$80;5)*1<ЛЕВСИМВ(D$20:D$80;5)*1;1;0);0)*1;ЕСЛИОШИБКА(ЕСЛИ(ПРАВСИМВ(D$20:D$80;5)*1<=$D95;0;1);0)*1)"
End Sub
Друзья, помогите нубу Недавно начал изучать VBA. Собственно, в ячейки формулу-то он вставляет, однако везде, где есть ПРАВСИМВ или ЛЕВСИМВ он вставляет ее в виде
Цитата
ПРАВСИМВ(@E$20:E$80;5)
Из-за @ не вычисляется верно. Как исправить? Что делаю не так? Файлик не стал прикладывать, поскольку без разницы куда вставлять... Проблема в коде
Необходимо связывать несколько ячеек на разных листах. При этом, в данных ячейках - выпадающий список. Если я изменил ячейку B2 на листе Макро_очередь, то на листе РМ ячейка C2 должна принять то же значение, на листе Переменные D2 должна принять то же значение. И наоборот.
При изменении любой из ячеек на взаимосвязанных листах - изменяются другие на то же значение с сохранением формата. (Даже если в ячейке число, которое является текстовым форматом, нужно чтобы в связанные ячейки вставилось число в текстовом формате)
Такая задача необходима под несколько ячеек, которые могут быть в разных частях листов. Пример: РМ → C2 взаимосвязан с Переменные → D2 и взаимосвязан с Макро_очередь → B2 (при изменении в одной, меняются все, с сохранением формата) Переменные → D3 Взаимосвязан с РМ → C5 и взаимосвязан с Макро_очередь → E3 (при изменении в одной, меняются все, с сохранением формата)
Таких взаимосвязей может быть много. Ожидается итоговый файл с комментариями, чтобы можно было дописать код, основываясь на вашем для решения этой же задачи при добавлении новых взаимосвязанных ячеек на разных листах.
Телефон есть в профиле, привязан к телеграмму. Либо через [Удалено]
Спасибо большое! @evgeniygeo, скажите, пожалуйста, как в код добавить если взаимозависимые ячейки будут находиться ниже по строкам? Cells(Target.Row, 3) - здесь понял, что нужно увеличивать значение "3" - будет двигаться столбец. А как сделать движение по строкам?
Код
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("B2:B3")) Is Nothing Then
Application.EnableEvents = False
Sheets("РМ").Cells(Target.Row, 3) = Target.Value
Sheets("Переменные").Cells(Target.Row, 3) = Target.Value // Добавил сюда строчку. Работает на 3 листах
Application.EnableEvents = True
End If
End Sub
Какая задача встала? Необходимо связывать несколько ячеек на разных листах. При этом, в данных ячейках - выпадающий список. Если я изменил ячейку B2 на листе Макро_очередь то на листе РМ ячейка C2 должна принять то же значение Если я изменил ячейку C2 на листе РМ то на листе Макро_очередь ячейка B2 должна принять то же значение (грубо говоря наоборот, работает в обе стороны)
То же самое и с ячейкой на одну ниже B3 (Макро_очередь) → C3 (РМ) и в обратную сторону
Файл примера, естественно, прикрепляю. Заранее благодарю за помощь.
Можете не объяснять почему именно так... Я дуб дубом в VBA... Буду признателен за рабочий вариант, чтобы на примере его я мог добавить дополнительные ячейки в взаимосвязь позже, скопировав часть кода. Если VBA для выпадающего списка отличается, то сделайте, пожалуйста, часть кода для ячеек B4 (Макро_очередь) → C4(РМ)
Очень часто нужна взаимосвязь с 3 листами, буду признателен, если Пропишете взаимосвязь на листы Макро_очередь B2,B3,B4 → Переменные D2,D3,D4 → РМ C2,C3,C4 (Расположил в разных местах листа, чтобы потом не задавал вам глупых вопросов и смог прописать сам по образу и подобию)