Прогресс выполнения процедуры

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Прогресс выполнения процедуры

Сообщение alibek » 03.12.2003 (Ср) 12:55

Предлагаю формочку, которая позволяет отображать процесс загрузки (например) информации. Форма открывается модально, но отображением прогресса управляет родительствая форма.

Пример использования (работает только в формах или классах):
Форма frmMain, на форме имеется CommandButton cmdStart.
Код: Выделить всё
Option Explicit

Public Sub DoProcess()
Dim C As Long, I As Long
frmProgress.SetTitle "Тестовый проход"
For C = 1 To 1000
  If C Mod 50 = 0 Then frmProgress.SetText "Обработано строк: " & Format$(C)
  If C Mod 10 = 0 Then frmProgress.SetPercent C/10
Next C
Unload frmProgress
End Sub

Public Sub DoCancel()
Unload frmProgress
MsgBox "Отменено!"
End Sub

Private Sub Form_Load()
cmdStart.Caption = "Start"
End Sub

Private Sub cmdStart_Click()
frmProgress.Init Me, "DoProcess", Me, "DoCancel"
Set frmProgress = Nothing
End Sub
Lasciate ogni speranza, voi ch'entrate.

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 03.12.2003 (Ср) 14:24

Интересно, но...

1. Выход сделан не правильно
Надо бы чуть подправить.
Код: Выделить всё
Option Explicit

Private Canceled As Boolean

Public Sub DoProcess()
   
    Dim C As Long, I As Long
   
    Canceled = False
    frmProgress.SetTitle "test"
    For C = 1 To 1000
        If C Mod 50 = 0 Then frmProgress.SetText "rows: " & Format$(C)
        If C Mod 10 = 0 Then frmProgress.SetPercent C / 10
        DoEvents
        If (Canceled) Then Exit For
    Next
    Unload frmProgress
    If (Canceled) Then MsgBox "Canceled!"
End Sub

Public Sub doCancel()
    Canceled = True
End Sub

Иначе форма закрывается, а цикл не завершается. И без DoEvents форма не реагирует на нажатие Cancel.

2. А зачем для прогресса и стопа передавать два объекта? Просто не вижу в этом необходимости и смысла.

3. Чтобы не заморачиваться с Mod'ами и ломать себе голову как долго будет выполняться один проход цикла, можно просто обновлять данные через фиксированный интервал времени, например, каждые пол секунды.
Код: Выделить всё
Public Sub DoProcess()
   
    Dim C As Long, I As Long
    Dim ShowTime!
   
    Canceled = False
    frmProgress.SetTitle "test"
    ShowTime = Timer()
    For C = 1 To 1000
       
        If (Timer() - ShowTime > 0.5) Then
            ShowTime = Timer()
            frmProgress.SetText "rows: " & Format$(C)
            frmProgress.SetPercent C / 10
            DoEvents
        End If
        If (Canceled) Then Exit For
    Next
    Unload frmProgress
    If (Canceled) Then MsgBox "Canceled!"
End Sub

Для долгих циклов обновление будет происходить реже, но не чаще чем каждые пол секунды

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 03.12.2003 (Ср) 17:06

Тоже скажу :)
Во-первых, вместо feedback я бы определил интерфейс, и заимплементил его в вызывающей форме.
А во-вторых, чем прогрессбар не устраивает? :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 08.12.2003 (Пн) 12:06

Согласен по всем пунктам :)
В оправдание скажу:
Пример использования я делал на скорую руку, флаговую переменную для отмены я конечно делал. Забыл просто. И отдельный объект для выхода тоже пожалуй лишний. Ну не подумал, простите :)
Относительно обновления по таймеру -- это кому как. Когда цикл пробегается большое число раз и выполняется долго, тогда я так и делаю, но для непродолжительных процессов можно сделать попроще.
Насчет интерфейсов -- не люблю я их :) Так эта форма практически вещь в себе, бери и используй. А с ними надо еще и интерфейс заводить, инициализировать. Вообщем о вкусах не спорят :)
А прогрессбар меня устраивает, но у этой формы другая задача. Во-первых, она более информационна, чем прогрессбар. А во-вторых у нее есть замечательный побочный эффект -- форма модальная и пользователь не сможет ничего тыкать, пока она не закроется :)
Lasciate ogni speranza, voi ch'entrate.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, SemrushBot, Yandex-бот и гости: 44

    TopList  
cron