【问题标题】:Smooth running marquee text in excel在 Excel 中平滑运行选取框文本
【发布时间】:2018-04-02 14:39:00
【问题描述】:

我正在 Excel 2013 中创建选取框文本。由于 Microsoft Web 浏览器控件在 Excel 2013 和 2016 中不起作用,因此我使用了以下 VBA 代码:

Sub DoMarquee()
    Dim sMarquee As String
    Dim iWidth As Integer 
    Dim iPosition As Integer
    Dim rCell As Range 
    Dim iCurPos As Integer 

    'Set the message to be displayed in this cell
    sMarquee = "This is a scrolling Marquee." 

    'Set the cell width (how many characters you want displayed at once
    iWidth = 10

    'Which cell are we doing this in?
    Set rCell = Sheet1.Range("M2") 

    'determine where we are now with the message. InStr will return the position
    ' of the first character where the current cell value is in the marquee message 
    iCurPos = InStr(1, sMarquee, rCell.Value)

    'If we are position 0, then there is no message, so start over 
    ' otherwise, bump the message to the next characterusing mid 
    If iCurPos = 0 Then 
        'Start it over 
        rCell.Value = Mid(sMarquee, 1, iWidth) Else 
        'bump it
        rCell.Value = Mid(sMarquee, iCurPos + 1, iWidth) 
    End If 

    'Set excel up to run this thing again in a second or two or whatever 
    Application.OnTime Now + TimeValue("00:00:01"), "DoMarquee" 

End Sub

在excel中每秒都在反映,有没有办法以毫秒为单位进行反映,以便它可以显示一些流畅的运行。更多的问题是,它只有在完全滚动后才会再次启动。有没有办法让它在等待整个文本滚动的情况下连续滚动。

【问题讨论】:

    标签: vba excel smooth-scrolling marquee


    【解决方案1】:

    对于您的亚秒级功能,请使用 API 调用。

    Option Explicit
    
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    
    Public Sub DoMarquee()
    
        Dim sMarquee As String
        Dim iWidth As Long
        Dim iPosition As Long
        Dim rCell As Range
        Dim iCurPos As Long
    
        sMarquee = "This is a scrolling Marquee."
        iWidth = 10
    
        Set rCell = Sheet1.Range("M2")
    
        iCurPos = InStr(1, sMarquee, rCell.Value)
    
        If iCurPos = 0 Then
            rCell.Value = Mid(sMarquee, 1, iWidth)
        Else
            rCell.Value = Mid(sMarquee, iCurPos + 1, iWidth)
        End If
    
        Sleep 100
        Application.Run "DoMarquee"
    
    End Sub
    

    如果在 32 位 机器上删除 PtrSafe,则变为:

    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    

    编辑:

    1)许多用户已经注意到堆栈空间外消息的调用频率。

    @Sorceri 已正确指出您可以重新工作为:

    Set rCell = Nothing
    DoEvents
    Sleep 100
    Application.OnTime Now, "DoMarquee"
    

    2)我不知道逐个字母的部分,所以我将向您推荐他/她关于将 iWidth 拉入全局变量的答案。

    请记住,您可能希望修改以下内容以考虑@Sorceri 的 iWidth;我为超链接提供了以下版本 2“软糖”,针对堆栈外进行了修改,其中包括对 32 v 64 位版本的测试以确保兼容性。更多关于兼容性的信息here

    版本 2:

    Option Explicit
    
    #If Win64 Then
        Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    #Else
        Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    #End If
    
    Public Sub DoMarquee()
    
        Dim sMarquee As String
        Dim iWidth As Long
        Dim iPosition As Long
        Dim rCell As Range
        Dim iCurPos As Long
    
        sMarquee = "This is a scrolling Marquee."
        iWidth = 10   
        Set rCell = Sheet1.Range("M2")
    
        rCell.Parent.Hyperlinks.Add Anchor:=rCell, Address:="https://www.google.co.uk/", TextToDisplay:=rCell.Text      
        rCell.Font.ThemeColor = xlThemeColorDark1 
        iCurPos = InStr(1, sMarquee, rCell.Value)
    
        If iCurPos = 0 Then
            rCell.Value = Mid(sMarquee, 1, iWidth)
            rCell.Hyperlinks(1).TextToDisplay = rCell.Text
            FormatCell rCell
        Else
            rCell.Value = Mid(sMarquee, iCurPos + 1, iWidth)
            On Error Resume Next
            rCell.Hyperlinks(1).TextToDisplay = rCell.Text
            On Error GoTo 0
            FormatCell rCell
        End If
    
        Set rCell = Nothing      
        DoEvents
        Sleep 100
        Application.OnTime Now, "DoMarquee"
    
    End Sub
    
    Public Sub FormatCell(ByVal rng As Range)
    
        With rng.Font
            .Name = "Calibri"
            .Size = 11
            .Underline = xlUnderlineStyleSingle
            .Color = 16711680
        End With
    
    End Sub
    

    【讨论】:

    • 感谢 QHarr。如果我想添加具有多个超链接的文本怎么办。如何使这些超链接起作用?
    • 超链接?这是一个不同的问题吗?
    • 这个问题有答案还是缺少什​​么?
    • 非常酷,我不知道你能做到这一点... :) ...*除了* 不幸的是它对我来说崩溃了。 :( 我正在使用Office 2016 CTR 32-bit on Windows 7 64-bit。不管有没有PtrSafe,它都会滚动选框几秒钟,然后我得到一个Out of Stack Space 错误。有时我可以点击Debug,其他时候Excel 只是崩溃/关闭。(我在尝试之间重新启动。)
    • @omprakash 这就是为什么我倾向于不帮助那些低分的人。 QHarr 在他的帖子中付出了很多努力,您至少可以说明它是否解决了问题,如果解决了,请将其标记为已回答。
    【解决方案2】:

    我无法获得停止堆栈空间不足的示例,因为堆栈上有许多对 DoMarquee 方法的调用。另外,我认为一个选框一个字一个字地写出来。所以使用 Application.OnTime 事件来创建选取框。我还取出了 iWidth 并将其设为全局变量。

    Option Explicit
    Private iWidth As Long
    
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    
    Public Sub DoMarquee()
    
        Dim sMarquee As String
    
        Dim iPosition As Long
        Dim rCell As Range
        Dim iCurPos As Long
        Dim txtMarquee As String
    
        sMarquee = "This is a scrolling Marquee."
    
    
        Set rCell = Sheet1.Range("M2")
        'check to see if the cell is empty
        If rCell.Value = "" Then
            'set the current position to 0 and iWidth to 0
            iCurPos = 0
            iWidth = 0
        Else
            'not blank so writing has started.  Get the position of the cell text
            iCurPos = InStr(1, sMarquee, rCell.Value)
        End If
    
    
        If iCurPos = 0 Then
            'it is zero so get the first character
            rCell.Value = Mid(sMarquee, iCurPos + 1, 1)
        Else
            If iWidth < 10 Then
                'width is less then ten so we have not written out the max characters,
                'continue until width is 10
                iWidth = iWidth + 1
                rCell.Value = Mid(sMarquee, 1, iWidth)
    
            Else
                'maxed the amount to show so start scrolling
                rCell.Value = Mid(sMarquee, iCurPos + 1, iWidth)
            End If
    
        End If
        'release range object
        Set rCell = Nothing
        'Application.OnTime to stop the stack out of space
        DoEvents
        Sleep 100
        Application.OnTime Now, "DoMarquee"
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2011-03-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      相关资源
      最近更新 更多