简体   繁体   English

尝试使用Windows API从电子表格打开音频文件

[英]Trying to open audio files from spreadsheet using windows API


I am struggling to open sound files from Excel in a way that will not reveal their names (it's a quiz). 我正在努力以一种无法显示其名称的方式从Excel中打开声音文件(这是测验)。 I suspect this should be dead easy but everything I have seen so far confuses the hell out of me. 我怀疑这应该很容易实现,但是到目前为止我所看到的一切都使我感到困惑。 I've built spreadsheet based quizzes before but not with sound files, I sort the order of the questions randomly and check my answers from values in hidden fields. 我之前建立了基于电子表格的测验,但没有声音文件,我随机对问题进行排序,并从隐藏字段中的值检查我的答案。 Correct answers are summed – easy spreadsheet functions with a bit of VBA with dynamic ranges. 总结正确的答案–带有动态范围的VBA的简单电子表格功能。

I just want to click on particular cells so that sound files open (from a file name in a hidden field a given offset from where I clicked), play a song and then close without revealing the file name , leaving me to type an answer in to the cell that caused the sound file to open. 我只想单击特定的单元格,以便打开声音文件 (从隐藏字段中的文件名到我单击的位置有一个给定的偏移量), 播放一首歌曲,然后关闭而不显示文件名 ,让我在其中键入答案到导致声音文件打开的单元格。

I am using Windows 10 and Excel 2013 with a 64 bit computer. 我在64位计算机上使用Windows 10和Excel 2013。
I want to access MP3 sounds from just an ordinary directory, specified by a link. 我只想通过链接指定的普通目录访问MP3声音。 I would use hyperlinks but: a) They introduce obnoxious “do you really think this link is safe” messages which people online have had mixed success dealing with – it involves fiddling with the registry and I'd rather not go there. 我会使用超链接,但:a)他们引入了令人讨厌的“您是否真的认为此链接是安全的”消息,网络上的人们在处理这些消息时取得了喜忧参半的消息–它涉及摆弄注册表,我不想去那里。 These display the name of the sound file which gives the game away! 这些显示声音文件的名称,该文件可以使游戏消失! b) Files open in other applications and give away the name of the file. b)在其他应用程序中打开文件并给出文件名。 It's a faff closing them down again – the quiz could be hundreds of calls. 这是让他们再次关闭的人–测验可能是数百个电话。 I thought about embedding files but that seems memory intensive - if each file can open and close from elsewhere then why stick them into a vast spreadsheet? 我曾考虑过嵌入文件,但似乎占用大量内存-如果每个文件都可以从其他位置打开和关闭,那么为什么要将它们粘贴到庞大的电子表格中? Instead I am trying to open the sound file using sndPlaySound which I believe is the 64 bit function that should accomplish the goal. 相反,我尝试使用sndPlaySound打开声音文件,我相信这是应该完成目标的64位函数。 There are posts everywhere about how to do this but none of them make the blindest bit of sense to me. 到处都有关于如何执行此操作的帖子,但是它们对我来说都不是最盲目的。 I tried to adapt the code from the URL below (for 32 bit – using the different sndPlaySound32) but to no avail. 我试图从下面的URL改编代码(32位-使用不同的sndPlaySound32),但无济于事。 http://www.cpearson.com/excel/PlaySound.aspx The code associated with my spreadsheet is (so far) very simple and responds to a user clicking in the Answer column of the quiz, getting the name of a sound file from a hidden location (using an offset) and calling the sndPlaySound function using the hidden file name. http://www.cpearson.com/excel/PlaySound.aspx与电子表格关联的代码(到目前为止)非常简单,可以响应用户单击测验的“答案”列,从中获取声音文件的名称隐藏位置(使用偏移量),然后使用隐藏文件名调用sndPlaySound函数。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

'Declare my sound directory
Dim SoundDirectory As String
SoundDirectory = "C:\Users\Andrew\Desktop\Bird Sounds\"

'The file name comes from a hidden cell using an offset function
Dim File As String
File = ActiveCell.Offset(columnOffset:=1).Value

'Declare variable link to be derived from SoundDirectory and File     variables
Dim Link As String

'Used to see if the user has moved to a cell used to open a sound file (2nd column)
Dim MyColumn As Long
If ActiveCell.Column = 2 Then
Link = SoundDirectory & File

‘The next line my machine hates this - it tells me there is a missing  "=" sign.

'sndPlaySound (Link,0)
End If
End Sub 

In a module I declared the sndPlaySound method from the windows API, altering it from the original because I believe it's sndPlaySound not sndPlaySound32 that I need with 64 bit 在一个模块中,我从Windows API中声明了sndPlaySound方法,将其与原始方法进行了更改,因为我认为它不是64位我需要的sndPlaySound32 sndPlaySound32

Public Declare Function sndPlaySound _
    Lib "winmm.dll" _
    Alias "sndPlaySoundA" ( _
    ByVal lpszSoundName As String, _
    ByVal uFlags As Long) As Long

I would be very grateful for any advice :) 我将不胜感激任何建议:)

I'm guessing your specific problem is evidenced by your comment: 我想您的评论可以证明您的特定问题:

'The next line my machine hates this - it tells me there is a missing "=" sign. “我的机器讨厌的下一行-它告诉我缺少一个缺失的“ =”符号。

That is due to the syntax in VBA, and doesn't have anything to do with the API call. 这是由于VBA中的语法所致,与API调用无关。 If you wrap the parameters in parenthesis you are telling the compiler that you care about the return value. 如果将参数包装在括号中,则表示正在告诉编译器您关心返回值。 Since you obviously don't care about the return (your code discards it), you'd need the Call keyword in front of it to signal that it can be discarded (and you should also explicitly pass the 0 as a Long - even better is to use the API constant declaration for SND_SYNC from mmsystem.h ): 由于您显然不关心返回(您的代码将其丢弃),因此您需要在其前面使用Call关键字来表示可以将其丢弃(并且还应该明确地将0传递为Long ,甚至更好)将使用来自mmsystem.h的 SND_SYNC的API常量声明:

Call sndPlaySound(Link, 0&)

If you omit the parenthesis, it is implicit that the return value can be ignored and the compiler doesn't complain about a missing assignment: 如果省略括号,则意味着可以忽略返回值,并且编译器不会抱怨缺少分配:

sndPlaySound Link, 0&

I also have no idea why Pearson declares the function returning a Long - it actually returns a BOOL , so it's safe to declare it in VBA as a Boolean ... 我也不知道为什么Pearson声明返回Long的函数-实际上返回了BOOL ,因此在VBA中将其声明为Boolean是安全的...

Public Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" ( _
    ByVal lpszSoundName As String, ByVal uFlags As Long) As Boolean

...or since you never use the return value, you can simply discard the return value by declaring it as a Sub : ...或者由于您从不使用返回值,因此可以简单地通过将其声明为Sub来放弃该返回值:

Public Declare Sub sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" ( _
    ByVal lpszSoundName As String, ByVal uFlags As Long)

That said, per MSDN, sndPlaySound is only maintained for backward compatibility - you should be using PlaySound instead: 就是说,对于MSDN,仅维护sndPlaySound是为了向后兼容-您应该改用PlaySound

Option Explicit

#If VBA7 Then
    Public Declare PtrSafe Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" _
        (ByVal pszSound As String, ByVal hmod As Any, ByVal fdwSound As Long) _
        As Boolean
#Else
    Public Declare Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" _
        (ByVal pszSound As String, ByVal hmod As Any, ByVal fdwSound As Long) _
        As Boolean
#End If

'fdwSound flag constants:
Public Const SND_SYNC = 0&
Public Const SND_ASYNC = 1&
Public Const SND_NODEFAULT = 2&
Public Const SND_MEMORY = 4&
Public Const SND_LOOP = 8&
Public Const SND_NOSTOP = 16&
Public Const SND_NOWAIT = &H2000&
Public Const SND_ALIAS = &H10000
Public Const SND_FILENAME = &H20000

Public Sub Example()
    Dim wave As String
    wave = Environ("SystemRoot") & "\Media\" & "chord.wav"
    If PlaySound(wave, 0&, SND_FILENAME Or SND_NODEFAULT) = False Then
        Debug.Print "File not found."
    End If
End Sub

Note: I doubt the PtrSafe declaration is required as the only pointer being passed is a String , which AFAIK gets handled automatically (please leave a comment if this isn't accurate). 注意:我怀疑是否需要PtrSafe声明,因为唯一要传递的指针是String ,AFAIK会自动处理该String (如果不正确,请发表评论)。 Note that hmod can be declared as Any because you'll always be passing it a 0& from VBA. 请注意,可以将hmod声明为Any因为您将始终从VBA传递0。

I was struggling to implement the advice you guys gave me (sorry, and I do hope that your attempts to educate me were useful to you!). 我正在努力执行你们给我的建议(对不起,我希望您尝试教育我的尝试对您有用!)。 I did however find a very simple work around, albeit not one that I understand entirely. 但是,我确实找到了一个非常简单的解决方法,尽管不是我完全理解的。 The work around uses a hyperlink from a hidden cell. 解决方法是使用隐藏单元格中的超链接。

http://spreadsheetpage.com/index.php/tip/playing_mp3_files_from_excel/ http://spreadsheetpage.com/index.php/tip/playing_mp3_files_from_excel/

Depending on what your default media player is the title may be more or less obvious as a giveaway. 视您的默认媒体播放器而定,标题可能或多或少是显而易见的。 My next stage is to build a macro to extract the file names from the directory into the hidden column and perhaps to extract the names of the species from metadata. 我的下一个阶段是构建一个宏,以将目录中的文件名提取到隐藏列中,并可能从元数据中提取物种的名称。 The former is something I have accomplished before (by stealing code from talented people!). 前者是我以前完成的事情(通过从有才华的人那里窃取代码!)。 I will attach some files to dropbox and link it here when I have the thing working full but in the meantime here's my code: 我可以将某些文件附加到保管箱,并在我可以正常工作时将其链接到此处,但是与此同时,这是我的代码:

'This function responds to a user clicking in the Answer column of the quiz, getting the name of a sound file from a hidden
'location and calling the sndPlaySound function using it
'Macro which will trigger if you place the cursor in the second row between the 2nd and nth rows as defined by where there is data
Private Sub Worksheet_SelectionChange(ByVal Target As Range)


'Find End Row, used to see if macro should run from cursor insertion event
Dim EndRow As Long

'Declare my directory
Dim SoundDirectory As String
SoundDirectory = "C:\Users\Andrew\Desktop\Bird Sounds\"

'File name will be derived from contents of a cell
Dim File As String

With ActiveSheet
EndRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With

'Exit the sub routine if it is not relevant to procede

If ActiveCell.Column <> 2 Or ActiveCell.Row = 1 Or ActiveCell.Row > EndRow Then
    Exit Sub
    End If

    'The file name comes from a hidden cell using an offset function

    File = ActiveCell.Offset(columnOffset:=1).Value

    'Built from SoundDirectory and File
    Dim Sound As String

    Sound = SoundDirectory & File

    Application.ScreenUpdating = True
    On Error Resume Next
   ActiveSheet.OLEObjects.Add(Filename:=Sound, Link:=False).Select
   If Err.Number <> 0 Then
     Application.ScreenUpdating = True
     MsgBox "Incorrect or missing hyperlink"
     Exit Sub
   End If
   Selection.Verb
   Selection.Delete

End Sub

End Sub 结束子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法使用Google电子表格API访问电子表格 - Not able to access spreadsheet using google spreadsheet API 使用poi api从电子表格中读取时间值 - Reading time values from spreadsheet using poi api 打开多个CSV文件,对每个文件进行排序和过滤,将其放置在主电子表格Macro / VBA中 - Open multiple CSV files, sort and filter the data from each one, place in master spreadsheet Macro/VBA 使用 ADODataset 组件打开 Excel 电子表格 - Using ADODataset component to open an Excel Spreadsheet 使用vba打开上次修改的Excel电子表格 - open last modified excel spreadsheet using vba 在Windows系统上使用默认应用程序打开Excel文件 - Open Excel files using default application on windows system 尝试将数据从网站写入 Excel 电子表格 - Trying to write data from a website to an Excel spreadsheet 尝试将数据从 XML 移动到 Excel 电子表格 - Trying to move data from XML to an Excel spreadsheet 使用 VBA 将所有内容从打开的记事本复制到电子表格中,而无需保存记事本 - Copy everything from an open notepad into a spreadsheet using VBA without having to save the notepad 我正在尝试使用VBA宏将信息从excel电子表格写入Powerpoint - I am trying to write information from an excel spreadsheet to a Powerpoint using VBA macros
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM