после установки x64 офиса - формулы полностью нагружают все 100% потоки процессора и справа снизу в строке состояния пишет количество нагруженных процессоров но сам vba код работает только в однопоточном режиме, загружая процессор на 5-15%
есть ли какие-то опции по включению всех потоков в vba? бывают ли вообще многопоточные компиляторы в программировании?
как объединить несколько ячеек в одну с сохранением всех цветов? кто-то прорабатывал такую процедуру?
тут есть два момента: 1. обрабатывать нужно посимвольно, т.к. в исходных ячейках может быть несколько цветов текста внутри каждой ячейки, т.е. цвет текста нельзя считывать со всей ячейки 2. этот код имеет максимальную длину 255:
т.е. посимвольно удлинять результирующую строку и тут же менять цвет в этом же цикле сработает только до длины 255
одно решение есть тут, но страдает от ошибки переполнения 255 и не учитывает разный цвет внутри исходных ячеек
Код
Sub Tester()
With ActiveSheet
AddValue .Range("A1"), "Hello", vbRed
AddValue .Range("A1"), "Hello", vbGreen
AddValue .Range("A1"), "Hello", vbBlue
End With
End Sub
Sub AddValue(rngVal As Range, val, theColor As Long)
Const SEP As String = " "
Dim firstChar As Long, extra As Long
firstChar = 1 + Len(rngVal.Value)
extra = IIf(firstChar = 1, 0, 1)
With rngVal
.Characters(firstChar).Text = IIf(Len(rngVal.Value) > 0, SEP, "") & val
.Characters(firstChar + extra, Len(val)).Font.Color = theColor
End With
End Sub
ещё одно из решений есть тут, но страдает от ошибки переполнения 255 Сцепляет с сохранением форматирования выделенные строки и помещает результат справа от выделения. Ячейка куда записывается результат сначала затирается
Код
Sub RunConcat()
ConcatenatewithFormat Selection, ThisWorkbook.ActiveSheet.Cells(Selection.Row, Selection.Column + Selection.Columns.Count)
End Sub
Sub ConcatenateWithFormat(InputRange As Range, OutPutRange As Range)
Dim i As Integer, q As Variant
Dim sText As String, c As String, A As Variant
Dim oChars As Characters, n As Integer
OutPutRange.Clear: n = 0
For Each A In InputRange
sText = A.Text
For i = 1 To Len(sText)
Set oChars = A.Characters(i, 1)
Set q = OutPutRange.Characters(i + n, 1)
q.Caption = oChars.Caption
With oChars
q.Font.Bold = .Font.Bold
q.Font.Name = .Font.Name
'q.Font.Color = .Font.Color
q.Font.ColorIndex = .Font.ColorIndex
q.Font.FontStyle = .Font.FontStyle
q.Font.OutlineFont = .Font.OutlineFont
q.Font.Size = .Font.Size
q.Font.Strikethrough = .Font.Strikethrough
q.Font.Subscript = .Font.Subscript
q.Font.Superscript = .Font.Superscript
q.Font.Underline = .Font.Underline
End With
Next i
n = n + Len(sText)
Next A
End Sub
пока что думаю алгоритм такой: v1 1. сначала выгрузить сырое сцепленное Value в результирующую ячейку 2. пройтись по исходным ячейкам и изменение цвета текста записать в словарь или коллекцию в виде [номер символа, индекс нового цвета] 3. покрасить итоговый сырой результат на основе этого словаря или коллекции 4. если нужно сохранить не только цвет, но и форматирование - то писать кодировку вида Font_Size_Bold_Underline_italic_Color, например Arial_12_NoBold_UL_Noit_FFFF00, хотя в данном случае возможно проще будет сделать на многомерном массиве, чтобы не сплитать и не расшифровывать эту кодовую строку форматирования
v2 а можно так: 1. сцепить сырой текст из всех исходников в результат 2. покрасить текст функцией выше, заквотив в ней две строки - 1. предочистка результирующей ячейки и 2. посимвольное впечатывание символа в результирующую ячейку v2 успешно отрабатывает на длине более 255
таким образом можно переделать пару строк в ConcatenateWithFormat и получить процедуру, которая успешно отработает и на разных цветах и на длине более 255, вдобавок можно добавить кастомный сепаратор между значениями исходных ячеек и фильтр по ячейкам
да, Shell.Explore помогла только если открыт рабочий стол через InvokeVerbEx, то Shell.Explore уже не откроет новое, а просто активирует.
1. если вручную открыто 3 рабочих стола, потом InvokeVerbEx откроет 4-ое окно (игнорируя ранее открытые), и Explore активирует это 4-ое окно 2. если вручную открыто 3 рабочих стола, и сразу Explore, то открываются новые окна таким образом - у окна, открытого InvokeVerbEx , некий особый статус
ниже: обычная папка - это та которая не нужна (если вручную идти в мои документы\рабочий стол) уникальная папка с синей иконкой - тот рабочий стол, который нужен - если тыкать на рабочий стол в боковом меню любой папки
1. если открыта "обычная" папка рабочий стол - то открывает всё равно новое окно с уникальной синей иконкой 2. если уже открыто хотя бы одно окно с уникальной иконкой - то активирует его 3. если открыто несколько окон с уникальной синей иконкой - то активирует самое раннее открытое 4. если не открыто ни одного окна с уникальной синей иконкой - то открывает новое нужное окно
таким образом - это лучше, чем всё, что у меня было до этого, т.к. первая команда которая умеет открывать рабочий стол с синей уникальной иконкой и всё ещё - эта команда не может открыть 3 отдельных окна. есть такая же команда, только с принудительным открытием нового окна?
Как открыть рабочий стол? (vba, winapi, win7) по какому адресу он находится?
в идеале бы получить CLSID в реестре прописан "Desktop" ::{00021400-0000-0000-C000-000000000046}, но он никуда не ведёт "file:///C:/Users/Admin/Desktop" открывает папку с рабочим столом (на картинке слева) а нужно именно виндовый рабочий стол с уникальной иконкой (на картинке справа)
инсталятор просто распаковывает одну DLL в отдельную папку - C:\Program Files (x86)\Office Automation\Smart Indenter\VBA6 как его подключить к офису выше 2003 ? через VBA - Tools - References - Browse - IndenterVBA.DLL - не подключается
кроме каспера есть ещё 60 других антивирусов с подключением с таким же успехом можно вообще ни один антивирус не ставить и говорить, что вирусов не существует в природе
как автоматически проставить табуляцию или отступы в vba коде? есть ли такая кнопка в самом VBA в экселе? если нету, то есть ли онлайн сервисы куда можно вставить сырой код и забрать код с отступами?
есть такой код:
Код
Sub TabTest()
If i = 1 Then
j = 2
End If
End Sub
нужно сделать из него такой:
Код
Sub TabTest()
If i = 1 Then
j = 2
End If
End Sub
-- вручную в каждой строке Tab и Shift+Tab не предлагать
Тип данных Long (Visual Basic) Содержит 64-разрядные (8-байтовые) целые числа со знаком в диапазоне от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 (9,2...E+18).
оказывается у них ещё и бейсики разные - один для офиса, а второй для дотнета
Цитата
ZVI написал: переменные типа Variant при компилировании кода приведены к типу aa#, т.е. к double
жаль у Variant нет короткого объявления хотя наоборот есть - оно без короткого знака
Код
Sub sdd()
Dim a0 As Variant 'All types
a1! = 1 'Single / -3.402823E38 to -1.401298E-45, 1.401298E-45 to 3.402823E38
a2@ = 1 'Currency / -922,337,203,685,477.5808 to 922,337,203,685,477.5807
a3# = 1 'Double / -1.79769313486232E+308 to -4.94065645841247E-324, 4.94065645841247E-324 to 1.79769313486232E+308
a4$ = 1 'String / 0 to 2,147,483,647 characters
a5% = 1 'Integer / -32,768 to 32,767
a6^ = 1 'LongLong / -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
a7& = 1 'Long / -2,147,483,648 to 2,147,483,648
a8 = 1 'Variant 'All types
End Sub
вот три строки, 1 выдаст ошибку, а 2 и 3 не выдадут хотя непонятно как это работает - если плюс изменил ситуацию, значит тип мат операции имеет значение а дальше в 3й строке мы убрали нолик около лонга - на лонг a1 этот ноль вообще не влияет, а каким образом он влияет на a2 тоже не понятно. т.е. если учитывается общий результат справа от равно, то наличие лонга должно решать все проблемы, т.к. справа 10 нулей, а у лонга 18
или вот = справа два лонга, максимум 18 разрядов, а слева 300 разрядов, число 10 разрядов, но выдает ошибку, пока не сделаешь a1# или a2# за всю практику первый раз столкнулся напрямую с перемножением в vba и это всё сделано как то криво косо неудобно
да еще если часто менять типы данных у переменной, то выскакивает ошибка о несоответствии. причем если ты менял с 1 на 10 - то эта ошибка никак не обойдётся, пока не введешь третье число типа 200, тогда он успешно обновляет тип данных (MS 2010)
в общем в любой непонятной ситуации пиши CDbl() или CLng() и это в большинстве случаев поможет
почему не вижу полного ФИО в твоём нике тогда? почему только неполная "М" ? ты что-то скрываешь? в чём-то замешан? щас бы в инете к никам придираться. ikki то очень осмысленный ник, намного круче йцукена надеюсь регистрацию на форуме по тилибону скоро прикрутят? + геолокацию ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- последние две строки выдают ошибку как полечить?:
загружаю файл в string потом делю на массив строк обрабатываю каждую строку склеиваю txt = txt & s сохраняю через ADODB.Stream
и вот именно на txt = txt & s идёт накопительная задержка если txt уже длинная (более 10000 строк), то к ней долго клеится новая строка
а через FSO.OpenTextFile ForAppending сохранять неудобно, т.к. поддерживает очень мало кодировок
вот таймер по каждому склеиванию + общая длина переменной txt: в последнем столбце видно как падает скорость склеивания симв/сек
Цитата
timer
Δ timer
len txt
Δ len
Δ len / Δ timer
0,164
0,164
30826
30826
187 963
0,373
0,209
63112
32286
154 490
0,648
0,275
102291
39179
142 267
0,984
0,336
137951
35660
106 151
1,476
0,492
182898
44947
91 321
2,113
0,637
227332
44434
69 786
2,959
0,846
271972
44640
52 784
4,369
1,41
327410
55438
39 313
6,16
1,791
380373
52963
29 571
8,244
2,084
432141
51768
24 841
10,406
2,162
494479
62338
28 832
12,849
2,443
549227
54748
22 407
15,439
2,59
590227
41000
15 831
18,22
2,781
627428
37201
13 376
вопрос: 1. есть ли у ADODB.Stream функция дозаписи в имеющийся файл? 2. если нету, то как правильно клеить длинные строки? проверять на длину txt и при превышении условных 200 000 использовать новую чистую string txt[2] txt[3] , а потом склеить txt[1] txt[2] txt[3] перед сохранением в файл ?
Пытливый написал: А вам куда НА САМОМ деле и ЧТО надо поставить?
в ТЗ идёт разговор про вставку в "Аванс!AH16" а при проверке прилагаемого решения он вставляет формулу на совершенно другой новый чистый лист и жалуется, что получается не то что ему надо
либо, чтобы запуск программы не гонять каждый раз, можно экселем создавать в папке с этой программой txt файл "60.txt" "70.txt", а она сама будет брать процент из имени этого файла
Таким образом она будет отображать ход выполнения макроса в своём окне на панели задач Ей даже можно иконку XLS скормить и любой Title подкинуть Может ли кто-нибудь написать такую? .NET Sample Interop Library https://rsdn.org/article/winshell/taskbar7.xml
или может можно на WinAPI CreateWindowEx создать окно с прогресс баром как-то
Посмотрел, там же опять пользовательские формы внутри самого Excel. Я же говорю про Windows кнопку на панели задач внизу, чтобы прогресс отображался прямо на кнопке Excel, что умеет делать любое приложение