Не смог уменьшить файл до нужного размера, поэтому не приложил.
Суть проблемы:
В модуле кода Листа1 прописан код, событие которого инициирует процедуру подбора параметров при изменении данных листа:
[vba]
Код
Private Sub Worksheet_Calculate() Dim a As Range, b As Range Set a = Range("ER45:ER78") Set b = Range("ES45:ES78") If Sheets("Лист2").Range("B3") = 1 Then For i = 1 To a.Count If Abs(a.Cells(i).Value) > 1 Then a.Cells(i).GoalSeek Goal:=0, ChangingCell:=b.Cells(i) End If Next End If End Sub
[/vba]
Процесс подбора параметров занимает около 30 секунд.
Как сделать так, чтобы находясь на листе Лист2 и меняя исходные данные, которые используются для расчетов на Листе 1, на экране появлялся индикатор выполнения макроса на Листе1?
Поискав в сети примеры "прогрессбаров", так и не смог применить их к своему примеру.
Заранее спасибо...
Здравствуйте!
Не смог уменьшить файл до нужного размера, поэтому не приложил.
Суть проблемы:
В модуле кода Листа1 прописан код, событие которого инициирует процедуру подбора параметров при изменении данных листа:
[vba]
Код
Private Sub Worksheet_Calculate() Dim a As Range, b As Range Set a = Range("ER45:ER78") Set b = Range("ES45:ES78") If Sheets("Лист2").Range("B3") = 1 Then For i = 1 To a.Count If Abs(a.Cells(i).Value) > 1 Then a.Cells(i).GoalSeek Goal:=0, ChangingCell:=b.Cells(i) End If Next End If End Sub
[/vba]
Процесс подбора параметров занимает около 30 секунд.
Как сделать так, чтобы находясь на листе Лист2 и меняя исходные данные, которые используются для расчетов на Листе 1, на экране появлялся индикатор выполнения макроса на Листе1?
Поискав в сети примеры "прогрессбаров", так и не смог применить их к своему примеру.
Ну да, примерно так, но чтобы табличка была активной и показывала, например, изменяющиеся проценты выполнения или меняющуюся в зависимости от степени выполнения полосу индикатора. В общем, чтобы пользователю было понятно, что компьютер не висит, а происходит исполнение макроса
Ну да, примерно так, но чтобы табличка была активной и показывала, например, изменяющиеся проценты выполнения или меняющуюся в зависимости от степени выполнения полосу индикатора. В общем, чтобы пользователю было понятно, что компьютер не висит, а происходит исполнение макросаLyova
Находил этот пример тоже, но не понимаю как к своему примеру прицепить, поскольку у меня макрос инициируется не не нажатием на кнопку, а событием другого листа. Да и, честно говоря, громоздкий он очень (для меня). Пока не очень понимаю класс модули. Может можно как-то без этого обойтись?
Находил этот пример тоже, но не понимаю как к своему примеру прицепить, поскольку у меня макрос инициируется не не нажатием на кнопку, а событием другого листа. Да и, честно говоря, громоздкий он очень (для меня). Пока не очень понимаю класс модули. Может можно как-то без этого обойтись?Lyova
Set a = Range("ER45:ER78") Set b = Range("ES45:ES78") If Sheets("Лист2").Range("B3") = 1 Then For i = 1 To a.Count If Abs(a.Cells(i).Value) > 1 Then a.Cells(i).GoalSeek Goal:=0, ChangingCell:=b.Cells(i) End If if i mod 5 = 0 then Application.StatusBar = "Перерасчёт..." & Round(i / a.Count * 100, 1) & "%" Next End If
Set a = Range("ER45:ER78") Set b = Range("ES45:ES78") If Sheets("Лист2").Range("B3") = 1 Then For i = 1 To a.Count If Abs(a.Cells(i).Value) > 1 Then a.Cells(i).GoalSeek Goal:=0, ChangingCell:=b.Cells(i) End If if i mod 5 = 0 then Application.StatusBar = "Перерасчёт..." & Round(i / a.Count * 100, 1) & "%" Next End If
Единственный ньюанс. Не сочтите за наглость. Визуализация конечно появилась, процент выполнения меняется, но поскольку это все в левом нижнем углу, то на большом экране не бросается в глаза и можно просто не заметить. Представляю просто себе уровень внимательности тех, кто потом будет пользоваться этим фалом.
Можно ли как-то еще больше визуализировать, чтобы полоса индикатора была или хотя бы шрифт, которым фраза "пересчет" и значения процентов отображаются был пожирнее
Спасибо огромное! Работает!
Единственный ньюанс. Не сочтите за наглость. Визуализация конечно появилась, процент выполнения меняется, но поскольку это все в левом нижнем углу, то на большом экране не бросается в глаза и можно просто не заметить. Представляю просто себе уровень внимательности тех, кто потом будет пользоваться этим фалом.
Можно ли как-то еще больше визуализировать, чтобы полоса индикатора была или хотя бы шрифт, которым фраза "пересчет" и значения процентов отображаются был пожирнееLyova
Можно начать делать собственный прогрессбар (на модальной форме, шоб уж наверняка заблокировал все приложение и отправил юзера курить ), но смысл?
Так что если хотите "красивости" - всё равно надо разбираться с прогрессбарами-классами, написанными до вас. Ну или всё же не надо жарить мозги процу? Зачем вы перерасчет запускаете при любых изменениях, да ещё с кучей подборов параметров? Нельзя разве сначала изменить все исходные данные, а затем - жмакнуть кнопку, делающую переасчет за один раз. И сюда же - прицепить красивые прогрессбары и т.п. И что-то мне говорит о том, что, может быть, вам и подбор параметра не требуется, так что расчеты можно делать быстро...
Со статусбаром - ольше ничего особо не придумать.
Можно начать делать собственный прогрессбар (на модальной форме, шоб уж наверняка заблокировал все приложение и отправил юзера курить ), но смысл?
Так что если хотите "красивости" - всё равно надо разбираться с прогрессбарами-классами, написанными до вас. Ну или всё же не надо жарить мозги процу? Зачем вы перерасчет запускаете при любых изменениях, да ещё с кучей подборов параметров? Нельзя разве сначала изменить все исходные данные, а затем - жмакнуть кнопку, делающую переасчет за один раз. И сюда же - прицепить красивые прогрессбары и т.п. И что-то мне говорит о том, что, может быть, вам и подбор параметра не требуется, так что расчеты можно делать быстро...AndreTM
Порылся на просторах, накопал более очевидную визуализацию (см.вложенный файл). Не сочтите за наглость (пардон за тавтологию). Не поможете вклеить (вариант 1) в Ваш вариант кода?
А без подборов никак нельзя. На одном листе исходные данные для расчета деятельности компании, в том числе в части условий лизинга техники и оборудования (ставка, сроки и т.д.). Лизинговые платежи рассчитываются аннуитетным методом, т.е. в расчетах подбирается равная сумма платежа каждый месяц, а эти суммы дальше идут в другие расчетные формы (CF, Баланс и т.д.). Соответственно, меняя любой из исходных показателей слетает весь график и надо делать подбор. Так он делается автоматически, а на кнопку каждый раз жать надо - лишнее действие
Порылся на просторах, накопал более очевидную визуализацию (см.вложенный файл). Не сочтите за наглость (пардон за тавтологию). Не поможете вклеить (вариант 1) в Ваш вариант кода?
А без подборов никак нельзя. На одном листе исходные данные для расчета деятельности компании, в том числе в части условий лизинга техники и оборудования (ставка, сроки и т.д.). Лизинговые платежи рассчитываются аннуитетным методом, т.е. в расчетах подбирается равная сумма платежа каждый месяц, а эти суммы дальше идут в другие расчетные формы (CF, Баланс и т.д.). Соответственно, меняя любой из исходных показателей слетает весь график и надо делать подбор. Так он делается автоматически, а на кнопку каждый раз жать надо - лишнее действиеLyova
А с символами попроще это сделать было никак? Например:
[vba]
Код
Sub test3() i1 = 30000 ' начальное значение цикла i2 = 80000 ' конечное значение цикла lenBar = 50 ' длина "псевдополоски" в статусбаре For i = i1 To i2 ' ... здесь - основные действия цикла ' далее - работа со статусбаром ip = Round((i - i1) / (i2 - i1), 3) ib = Int(ip * lenBar) Application.StatusBar = "Выполнено: " & ip * 100 & "% " & String(ib, "|") & String(lenBar - ib, ".") DoEvents Next Application.StatusBar = False End Sub
[/vba]
Переделать вашу процедуру сами сможете? Или всё надо "за вас"?
Set a = Range("ER45:ER78") Set b = Range("ES45:ES78") If Sheets("Лист2").Range("B3") = 1 Then For i = 1 To a.Count If Abs(a.Cells(i).Value) > 1 Then a.Cells(i).GoalSeek Goal:=0, ChangingCell:=b.Cells(i) End If if i mod 5 = 0 then ib = round((i-1)/(a.count-1),3): ip = Int(ip*50) Application.StatusBar = "Выполнено: " & ip * 100 & "% " & String(ib, "|") & String(50 - ib, ".") end if Next End If
А с символами попроще это сделать было никак? Например:
[vba]
Код
Sub test3() i1 = 30000 ' начальное значение цикла i2 = 80000 ' конечное значение цикла lenBar = 50 ' длина "псевдополоски" в статусбаре For i = i1 To i2 ' ... здесь - основные действия цикла ' далее - работа со статусбаром ip = Round((i - i1) / (i2 - i1), 3) ib = Int(ip * lenBar) Application.StatusBar = "Выполнено: " & ip * 100 & "% " & String(ib, "|") & String(lenBar - ib, ".") DoEvents Next Application.StatusBar = False End Sub
[/vba]
Переделать вашу процедуру сами сможете? Или всё надо "за вас"?
Set a = Range("ER45:ER78") Set b = Range("ES45:ES78") If Sheets("Лист2").Range("B3") = 1 Then For i = 1 To a.Count If Abs(a.Cells(i).Value) > 1 Then a.Cells(i).GoalSeek Goal:=0, ChangingCell:=b.Cells(i) End If if i mod 5 = 0 then ib = round((i-1)/(a.count-1),3): ip = Int(ip*50) Application.StatusBar = "Выполнено: " & ip * 100 & "% " & String(ib, "|") & String(50 - ib, ".") end if Next End If
у меня было что-то подобное, но захотелось чего-то нового... [vba]
Код
Option Explicit
Sub GetFor_() Dim lr As Long lr = 20000
Dim r As Long, sStB As String Dim c As Integer For r = 2 To lr Application.StatusBar = sObrStr(r, lr) & sSuff(CInt(r / lr * 100)) 'ActiveWindow.ScrollRow = r - 1 ' sStB = Application.StatusBar ' ' For c = 1 To 100 ' Application.StatusBar = sStB & sSuff(c) ' DoEvents ' Next c
DoEvents Next r Application.StatusBar = False End Sub
Function sObrStr(r As Long, lr As Long) As String sObrStr = "Обрабатывается строка: " & sNumber(r) & " из " & sNumber(lr) End Function
Function sSuff(c As Integer) As String sSuff = " " & String$(c, ChrW(9607)) End Function
Function sNumber(lNum As Long) As String Dim sRes As String
Dim sNum As String sNum = CStr(lNum)
Dim i As Integer, iDig As Integer For i = 1 To Len(sNum) iDig = Mid(sNum, i, 1) sRes = sRes & sDigit(iDig) Next i sNumber = sRes End Function
Function sDigit(iDig As Integer) As String If iDig = 0 Then sDigit = ChrW(9471) Else sDigit = ChrW(iDig + 10101) End If End Function
у меня было что-то подобное, но захотелось чего-то нового... [vba]
Код
Option Explicit
Sub GetFor_() Dim lr As Long lr = 20000
Dim r As Long, sStB As String Dim c As Integer For r = 2 To lr Application.StatusBar = sObrStr(r, lr) & sSuff(CInt(r / lr * 100)) 'ActiveWindow.ScrollRow = r - 1 ' sStB = Application.StatusBar ' ' For c = 1 To 100 ' Application.StatusBar = sStB & sSuff(c) ' DoEvents ' Next c
DoEvents Next r Application.StatusBar = False End Sub
Function sObrStr(r As Long, lr As Long) As String sObrStr = "Обрабатывается строка: " & sNumber(r) & " из " & sNumber(lr) End Function
Function sSuff(c As Integer) As String sSuff = " " & String$(c, ChrW(9607)) End Function
Function sNumber(lNum As Long) As String Dim sRes As String
Dim sNum As String sNum = CStr(lNum)
Dim i As Integer, iDig As Integer For i = 1 To Len(sNum) iDig = Mid(sNum, i, 1) sRes = sRes & sDigit(iDig) Next i sNumber = sRes End Function
Function sDigit(iDig As Integer) As String If iDig = 0 Then sDigit = ChrW(9471) Else sDigit = ChrW(iDig + 10101) End If End Function
поскольку это все в левом нижнем углу, то на большом экране не бросается в глаза и можно просто не заметить
Если в упрощённой до предела процедуре Сани [vba]
Код
Sub GetFor_() Dim R&, lR&: lR = 20000 For R = 2 To lR Application.StatusBar = "Обрабатотка: " & R & " из " & lR & " " & String(CInt(R / lR * 100), ChrW(&H25A1)) DoEvents Next R Application.StatusBar = False End Sub
[/vba] убрать разрешение прерывания для обработки событий DoEvents, то пока идёт прогресс (цикл) никто ничего сделать не сможет - на экране будут висеть "часики".
Можно начать делать собственный прогрессбар (на модальной форме, шоб уж наверняка заблокировал все приложение и отправил юзера курить )
Вот именно! Для того, чтобы сделать "объяву" с прогресс-баром на середине экрана, нужно форму делать. А это мало того, что лень, но и кроме того препятствует свободной вставке кода "куда надо", т.к. кроме текста процедуры нужно будет ещё и модуль формы за собой таскать.
поскольку это все в левом нижнем углу, то на большом экране не бросается в глаза и можно просто не заметить
Если в упрощённой до предела процедуре Сани [vba]
Код
Sub GetFor_() Dim R&, lR&: lR = 20000 For R = 2 To lR Application.StatusBar = "Обрабатотка: " & R & " из " & lR & " " & String(CInt(R / lR * 100), ChrW(&H25A1)) DoEvents Next R Application.StatusBar = False End Sub
[/vba] убрать разрешение прерывания для обработки событий DoEvents, то пока идёт прогресс (цикл) никто ничего сделать не сможет - на экране будут висеть "часики".
Можно начать делать собственный прогрессбар (на модальной форме, шоб уж наверняка заблокировал все приложение и отправил юзера курить )
Вот именно! Для того, чтобы сделать "объяву" с прогресс-баром на середине экрана, нужно форму делать. А это мало того, что лень, но и кроме того препятствует свободной вставке кода "куда надо", т.к. кроме текста процедуры нужно будет ещё и модуль формы за собой таскать.Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Пятница, 26.09.2014, 11:54
Переделать вашу процедуру сами сможете? Или всё надо "за вас"?
Если "за меня", то буду благодарен. Это не потому, что мне лень, а действительно сам не смогу. При исполнении Вашего кода знак "|" не появляется в динамике, проценты не меняются, как в Sub test3(). В течении всего выполнения висит не меняющаяся фраза "Выполняется 0%........"
Переделать вашу процедуру сами сможете? Или всё надо "за вас"?
Если "за меня", то буду благодарен. Это не потому, что мне лень, а действительно сам не смогу. При исполнении Вашего кода знак "|" не появляется в динамике, проценты не меняются, как в Sub test3(). В течении всего выполнения висит не меняющаяся фраза "Выполняется 0%........"
При исполнении Вашего кода знак "|" не появляется в динамике, проценты не меняются, как в Sub test3(). В течении всего выполнения висит не меняющаяся фраза "Выполняется 0%........"
А это у меня непроизвольная привычка - оставлять "ошибку для размышления" в быстрописном коде примера Чтобы вопрошающий задумался и поразбирался...
Цитата
if i mod 5 = 0 then ip = Round((i-1)/(a.count-1),3): ib = Int(ip*50) Application.StatusBar = "Выполнено: " & ip * 100 & "% " & String(ib, "|") & String(50 - ib, ".") end if DoEvents
При исполнении Вашего кода знак "|" не появляется в динамике, проценты не меняются, как в Sub test3(). В течении всего выполнения висит не меняющаяся фраза "Выполняется 0%........"
А это у меня непроизвольная привычка - оставлять "ошибку для размышления" в быстрописном коде примера Чтобы вопрошающий задумался и поразбирался...
Цитата
if i mod 5 = 0 then ip = Round((i-1)/(a.count-1),3): ib = Int(ip*50) Application.StatusBar = "Выполнено: " & ip * 100 & "% " & String(ib, "|") & String(50 - ib, ".") end if DoEvents