Макрос Powerpoint - основная проблема со счетчиком - PullRequest
1 голос
/ 24 июля 2011

Я делаю свой первый макрос Powerpoint 2007, и у меня возникают проблемы с его зависанием, и я не могу перейти к следующему слайду.Я могу нажать ESCAPE, чтобы выйти из слайд-шоу, но нажатие клавиши пробела или чего-либо еще не перейдет к следующему слайду.Через некоторое время просто вылетает.Я пришел из C ++ / Java, поэтому думаю, что это просто что-то базовое, чего мне не хватает.

По сути, я пытаюсь сделать встречный слайд, который считает дни / минуты / секунды от определенной даты.Когда слайд загружается, я хочу, чтобы он в реальном времени показывал, сколько времени прошло с этой даты.Я пропустил бесконечный цикл, который прекрасно работает для обновления времени, но затем не позволяет перейти к следующему слайду.

Вот мой код:

    Sub OnSlideShowPageChange(ByVal SSW As SlideShowWindow)
    'If SSW.View.CurrentShowPosition = 3 Then
    Do While SSW.View.CurrentShowPosition = 3    ' infinite loop
        Dim currentSlide As Integer
        currentSlide = SSW.View.CurrentShowPosition

        Dim startDate As Date
        Dim currentDate As Date
        Dim sngDiff As Single
        Dim lngDays As Long
        Dim lngHours As Long
        Dim lngMinutes As Long
        Dim lngSeconds As Long

        startDate = #7/22/2011 2:00:00 PM#
        currentDate = Now

        sngDiff = currentDate - startDate
        lngDays = CLng(sngDiff)
        sngDiff = sngDiff - lngDays
        lngHours = Hour(sngDiff)
        lngMinutes = Minute(sngDiff)
        lngSeconds = Second(sngDiff)

        With ActivePresentation.Slides(currentSlide)
            With .Shapes(2)
            .TextFrame.TextRange.Text = "It has been:" & lngDays & " Days " & lngHours & " hours " & lngMinutes & " minutes " & lngSeconds & " Seconds"
            End With
        End With

    DoEvents
    Loop
End Sub

ДелатьМне нужно послушать какое-нибудь нажатие кнопки, чтобы остановить этот бесконечный цикл, или как мне это сделать?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 24 июля 2011

Проблема в том, что ваша программа "владеет" приложением; пока он не выйдет, вы не сможете ничего сделать вручную (то есть перейти к следующему слайду).

Независимо от того, используете ли вы таймер в форме (и, кстати, элемент управления Timer не поставляется с VBA, как с VB), я думаю, что форма может быть вашим решением.

Пусть ваш обработчик событий немодально загрузит форму и завершит работу.

Код в форме может затем делать любые моды для слайдов или что угодно еще. Включайте DoEvents достаточно часто, чтобы не замедлять основное приложение, но код в форме будет выполняться независимо от того, что делает основное приложение.

Вам не нужно делать форму видимой (и, вероятно, не хотите).

0 голосов
/ 24 июля 2011

Форма пользователя - это то, что вы добавляете в редактор VBA; это то, что вы обычно воспринимаете как диалоговое окно, хотя формы могут использоваться для других целей и даже не должны становиться видимыми; вот что мы собираемся сделать здесь:

Option Explicit
Public bFormCodeRunning As Boolean

Sub FormDemo()

' Set a flag to let us know the code in the form
' is running
bFormCodeRunning = True

' "show" the form
UserForm1.Show vbModeless


End Sub

Sub KillForm()
' call this at some other point in the presentation
' when you're sure you're done running the form code

If Not bFormCodeRunning Then
    Unload UserForm1
End If

' You could actually call this from your slide change event handler

End Sub

Затем вставьте пользовательскую форму из меню, чтобы добавить новую форму; дважды щелкните по нему, чтобы просмотреть его код, и добавьте следующее:

Private Sub UserForm_Activate()

    ' Don't show my face
    Me.hide
    DoEvents

    ' prove that the form's loaded
    MsgBox "I'm well-formed"

    DoEvents
    ' and put your other code here

    ' and when the code's done, flag it
    bFormCodeRunning = False

End Sub
0 голосов
/ 24 июля 2011

Для задержки в контексте VBA обычно лучше использовать объект form_timer, поэтому в вашем коде есть:

If SSW.View.CurrentShowPosition = 3 Then
    Me.TimerInterval = 1000
Else
    Me.TimerInterval = 0
End If

или что-то подобное.Затем в форме кода таймера укажите свой код обновления часов

Private Sub Form_Timer()
// Your clock update code here
End Sub

Прошло много лет с тех пор, как я работал с VBA, поэтому я немного заржавел, но надеюсь, что это поможет.Как правило, для выполнения задач с потоками используются таймеры, а не циклы, VBA плохо с ними справляется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...