【问题标题】:Cannot change color of a shape in Excel无法在 Excel 中更改形状的颜色
【发布时间】:2019-10-07 09:13:21
【问题描述】:

VBA 新手在这里。 我正在开发一个使用我客户的外部 dll 的工作簿。 在工作表中,我有一个按钮,当按下该按钮时,会启动一个使形状变为橙色的例程,然后调用 API,最后使形状变为黑色。

神奇的是,它只工作“几次”。

以下代码位于模块内的子代码中:

Dim shapeToFlash As String
shapeToFlash = "SHAPE " & sheetName
Worksheets("GTE HOME").Shapes(shapeToFlash).Fill.ForeColor.SchemeColor = 53
Worksheets("HOME").Shapes(shapeToFlash).Fill.ForeColor.SchemeColor = 53

// API CALL (kind of long operation ~ 3/4 seconds)

Worksheets("GTE HOME").Shapes(shapeToFlash).Fill.ForeColor.SchemeColor = 0
Worksheets("HOME").Shapes(shapeToFlash).Fill.ForeColor.SchemeColor = 0

我无法分享有关 API 的详细信息。我只是用传统的语法声明:

#If Win64 Then
Private Declare PtrSafe Function IMB_set_value _
    Lib "path/API.dll" () As Long

#Else
Private Declare Function IMB_set_value _
    Lib "path/API.dll" () As Long

并且完美运行。

问题是第一个 SchemeColor(到 53)不起作用,这意味着 API 被调用,第二个 SchemeColor 也被调用(形状变黑)。只是为了测试,我尝试将第二个 SchemeColor 注释为 0(为 0),我注意到在这种情况下,在调用 API 后形状变为橙色!这建议我 Excel 创建一种要执行的命令的优先级队列,并且 API 调用在第一个 SchemeColor 之前执行:这显然与我的流程混乱。有没有办法强制 Excel 立即执行操作?失败还有其他原因吗?

P.S.:我已经分别执行了第一行 SchemeColor 代码,并且运行良好,所以我认为代码是正确的。 P.P.S.:我也试过用 RGB 代替 SchemeColor,结果是一样的。

【问题讨论】:

  • 当你说:不起作用,这是什么意思?你的形状不会改变颜色?另外,您能否尝试将颜色更改为更鲜艳的颜色……即黄色。您尝试设置的颜色有点暗,可能会被误认为是黑色
  • 该命令(代码中的第一个 SchemeColor)被完全忽略,因此它不会改变颜色。我也试过黄色,但没有任何改变
  • 如果在 API 调用之前和/或之后放置 DoEvents 会发生什么?
  • @Sam:这是我最初的想法,但即使使用DoEvents,直到代码结束时才会应用对形状的更新..
  • 在更新颜色后尝试:<reference to your worksheet>.Calculate。我还尝试过在形状前面有一个矩形。这意味着我可以更新矩形的透明度和矩形的颜色,而且效果也很好

标签: excel vba colors


【解决方案1】:

试试这个

Sub InitiateLongRunningOperation()
    Dim Argument as String

    HighlightShape
    Argument = "Argument Value"        
    Application.OnTime Now, "'LongRunningOperation """ & Argument & """'"
End Sub

Sub HighlightShape()
    Worksheets(1).Shapes(1).Fill.ForeColor.SchemeColor = 53
End Sub

Sub LongRunningOperation(AnArgument As String)
    Debug.Print AnArgument
    ' Replace the line below with your API call
    Application.Wait Now + TimeValue("0:00:03")

    Application.OnTime Now, "ResetShape"
End Sub

Sub ResetShape()
    Worksheets(1).Shapes(1).Fill.ForeColor.SchemeColor = 0
End Sub

它与Application.OnTime 一起使用来启动事件链,而无需等待所有事件都结束后再更新。 我已经更改了您的一些代码以使其更易于重现,但我认为您将能够很容易地遵循它。

【讨论】:

  • 有什么方法可以用参数指定 LongRunningOperation 吗?
  • 我现在已经更新了代码。根据文档,它不应该工作,但确实如此。
  • 它似乎工作!很抱歉打扰,但我找不到传递字符串参数而不是参数的方法。
  • 而不是纯字符串*
猜你喜欢
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 2020-12-09
  • 2020-11-24
相关资源
最近更新 更多