【问题标题】:Stop VBA to block Excel sheet when executing a function执行函数时停止 VBA 以阻止 Excel 工作表
【发布时间】:2017-07-13 15:59:53
【问题描述】:

我有以下 Excel 场景:

A1 的值为“A”,B2 = “B”,C3 = “C”

但它们是可以互换的。

在工作簿路径中有两个包含名为 A.wav、B.wav 和 C.wav 的 wav 文件的子文件夹

底部的代码允许我通过单击触发宏 PlayIt() 的按钮来播放 wav 文件。

我的问题是,当函数正在执行时,我无法在 Excel 中编辑我真正需要的单元格!好像是这样的

https://gifyu.com/images/GIF8d5e1.gif

感谢您的帮助!

音频播放代码:

Option Explicit

#If VBA7 Then
Public Declare PtrSafe Function PlaySound Lib "winmm.dll" _
  Alias "sndPlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
#Else
Public Declare Function PlaySound Lib "winmm.dll" _
  Alias "sndPlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
#End If

Const SND_SYNC = &H0
Const SND_ASYNC = &H1
Const SND_FILENAME = &H20000

Sub PlayTheSound(ByVal WhatSound As String)
    If Dir(WhatSound, vbNormal) = "" Then
        ' WhatSound is not a file. Get the file named by
        ' WhatSound from the Windows\Media directory.
        WhatSound = ThisWorkbook.Path & "\stimuli\" & "\1second\" & WhatSound
        If InStr(1, WhatSound, ".") = 0 Then
            ' if WhatSound does not have a .wav extension,
            ' add one.
            WhatSound = WhatSound & ".wav"
        End If
        If Dir(WhatSound, vbNormal) = vbNullString Then
            Beep            ' Can't find the file. Do a simple Beep.
            MsgBox "Could not find the file in the Path: " & WhatSound
            Exit Sub
        End If
    Else
        ' WhatSound is a file. Use it.
    End If

    PlaySound WhatSound, 0&, SND_ASYNC Or SND_FILENAME    ' Finally, play the sound.
End Sub

Sub PlayIt()
    PlayTheSound (Range("A1").Value)
    PlayTheSound (Range("B1").Value)
    PlayTheSound (Range("C1").Value & "e")
End Sub

【问题讨论】:

  • ByVal hModule As LongPtr。如果您的办公室是 x64,这可能就是原因。
  • @GSerg 如果我删除 ByVal hModule As LongPtr 并且只调用 PlaySound WhatSound, SND_ASYNC Or SND_FILENAME 我只会听到最后一个 wav 文件 PlayTheSound (Range("C1").Value & "e")
  • 你有ByVal hModule As Long。正确的是ByVal hModule As LongPtr
  • 试试doevents。更多详细信息请参见 link,您可以下载 this file 以及一些工作宏,您仍然可以在它们运行时与工作表进行交互。
  • @AshtonMorgan 总的来说,这是一个非常糟糕的建议,对于可以本机异步运行的函数尤其糟糕,并且在这种情况下无法实现,因为您需要注入 DoEvents 调用内部调用PlaySound

标签: excel vba


【解决方案1】:

您的声明有两个错误:hModule 应该是 LongPtr,并且您在实际调用 sndPlaySound 时使用了来自 PlaySound 的参数。

修正你的声明:

#If VBA7 Then
Public Declare PtrSafe Function PlaySound Lib "winmm.dll" _
  Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As LongPtr, ByVal dwFlags As Long) As Long
#Else
Public Declare Function PlaySound Lib "winmm.dll" _
  Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
#End If

【讨论】:

  • 这又引发了一个问题,现在只会播放 PlayIt() 的最后一行 PlayTheSound (Range("C1").Value & "e"),前 du 行被“跳过”...
  • 对不起,但是 VBA 菜鸟问题;别名实际上是做什么的?我似乎可以安全地删除它,并且只有这个:Public Declare PtrSafe Function PlaySound Lib "winmm.dll" _ (ByVal lpszName As String, ByVal hModule As LongPtr, ByVal dwFlags As Long) As Long 我提供的文件现在已更新。非常感谢!
  • @McTell 就像文档中所说的那样,当你开始一个新的声音时,它会停止当前播放的声音,除非你也通过SND_NOSTOP(你没有),在这种情况下它如果正在播放另一种声音,则不会播放任何内容。 Alias 用于从库中导出的名称与您要在代码中用于该函数的名称不同时使用。实际的函数名称是PlaySoundA,除非您愿意将其声明为PlaySoundA,否则您必须提供别名。如果您提供的别名与声明的名称相匹配,IDE 将删除它。
  • @McTell 这个函数没有简单的方法可以让声音按顺序播放。您可能想要查看其他一些媒体功能,或者在播放之前合并 wav 文件,即not difficult。您甚至可以在内存中执行此操作,并使用 SND_MEMORY 将指向字节数组的指针传递给 PlaySound
  • 抱歉,我很困惑,使用 SND_NOSTOP 无法解决我的问题,我应该使用合并方法吗?
猜你喜欢
  • 2019-09-25
  • 1970-01-01
  • 2017-04-21
  • 2019-11-05
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
相关资源
最近更新 更多