2012-02-28 72 views
5

我想通过VBA设置单元格的值。我用Google搜索,并看到一些决议:不能在VBA中将数据写入Excel 2007/2010中的单元格

Sheets("SheetName").Range("A1").value = someValue 
Sheets("SheetName").Cells(1,1).value = someValue 

有了这样的代码,我可以只读取单元格A1的数据,但我不能一个新的值设置为它。

更新

设置单元格A1值的代码是一个Function如下内放。

Function abb() 
    Sheets("SheetName").Range("A1").value = 122333 
    abb = 'any thing' 
End Function 

在单元格B2中,我设置了=abb()并按回车。我获得了#VALUE,但没有发生在A1。

把这段代码放在一个宏中,它可以工作。

我的问题是,如何让A1具有函数内的值?

+2

你有两种选择。可以将其作为子程序运行,也可以使用http://stackoverflow.com/q/8520732/641067中的UDF计时器解决方法。前者更容易。 – brettdj 2012-02-28 10:20:40

+1

如果你想让一个函数在A1中返回一些东西,那么函数调用应该在A1中输入。这就是Excel工作的方式。 – 2012-02-28 10:22:02

+0

为什么不用B2表单来修改B2表单然后填充A1?从你的代码中,函数不会更新,因为它没有任何参数。 – brettdj 2012-02-29 01:33:16

回答

10

从上面您的评论想如果输入
=abb()

那么这片的单元格A1西港岛线被设置为12333

这是任何单元格尝试这种方法

要更新的行选择要更新的单元格,并在其中放置一个值
Range("A1").Value = 122333

I don't want my Excel Add-In to return an array (instead I need a UDF to change other cells)

我从Kevin Jones aka Zorvek重新发布这片神奇因为它位于behind the EE Paywall(链路连接,如果任何人可以访问)

虽然Excel中严禁改变,不允许UDF的任意单元格,工作表, 或工作簿属性,有一种方法可以在使用Windows定时器和 序列中的Application.OnTime计时器调用UDF时实现此类更改。 Windows定时器必须在UDF中使用,因为 Excel将忽略UDF内的任何Application.OnTime调用。但是,因为 Windows计时器有限制(如果在编辑单元或打开 对话框时,如果 Windows计时器试图运行VBA代码,Excel将立即退出),它仅用于调度Application.OnTime 计时器,一个安全计时器,Excel只允许在单元格不被编辑且没有对话框打开的情况下被触发。

以下示例代码示出了如何从 启动Windows计时器一个UDF内,如何使用该计时器例程启动一个 Application.OnTime定时器,以及如何通过只知道 的UDF随后定时器信息执行的例程。下面的代码必须是 放置在一个常规模块。

Declare Function SetTimer Lib "user32" (_ 
     ByVal HWnd As Long, _ 
     ByVal nIDEvent As Long, _ 
     ByVal uElapse As Long, _ 
     ByVal lpTimerFunc As Long _ 
    ) As Long 

Private Declare Function KillTimer Lib "user32" (_ 
     ByVal HWnd As Long, _ 
     ByVal nIDEvent As Long _ 
    ) As Long 

Private mCalculatedCells As Collection 
Private mWindowsTimerID As Long 
Private mApplicationTimerTime As Date 

Public Function abb() 

' This is a UDF that returns the sum of two numbers and starts a windows timer 
' that starts a second Appliction.OnTime timer that performs activities not 
' allowed in a UDF. Do not make this UDF volatile, pass any volatile functions 
' to it, or pass any cells containing volatile formulas/functions or 
' uncontrolled looping will start. 

    abb = "Whatever you want" 

    ' Cache the caller's reference so it can be dealt with in a non-UDF routine 
    If mCalculatedCells Is Nothing Then Set mCalculatedCells = New Collection 
    On Error Resume Next 
    mCalculatedCells.Add Application.Caller, Application.Caller.Address 
    On Error GoTo 0 

    ' Setting/resetting the timer should be the last action taken in the UDF 
    If mWindowsTimerID <> 0 Then KillTimer 0&, mWindowsTimerID 
    mWindowsTimerID = SetTimer(0&, 0&, 1, AddressOf AfterUDFRoutine1) 

End Function 

Public Sub AfterUDFRoutine1() 

' This is the first of two timer routines. This one is called by the Windows 
' timer. Since a Windows timer cannot run code if a cell is being edited or a 
' dialog is open this routine schedules a second safe timer using 
' Application.OnTime which is ignored in a UDF. 

    ' Stop the Windows timer 
    On Error Resume Next 
    KillTimer 0&, mWindowsTimerID 
    On Error GoTo 0 
    mWindowsTimerID = 0 

    ' Cancel any previous OnTime timers 
    If mApplicationTimerTime <> 0 Then 
     On Error Resume Next 
     Application.OnTime mApplicationTimerTime, "AfterUDFRoutine2", , False 
     On Error GoTo 0 
    End If 

    ' Schedule timer 
    mApplicationTimerTime = Now 
    Application.OnTime mApplicationTimerTime, "AfterUDFRoutine2" 

End Sub 

Public Sub AfterUDFRoutine2() 

' This is the second of two timer routines. Because this timer routine is 
' triggered by Application.OnTime it is safe, i.e., Excel will not allow the 
' timer to fire unless the environment is safe (no open model dialogs or cell 
' being edited). 

    Dim Cell As Range 

    ' Do tasks not allowed in a UDF... 
    Application.ScreenUpdating = False 
    Application.Calculation = xlCalculationManual 
    Do While mCalculatedCells.Count > 0 
     Set Cell = mCalculatedCells(1) 
     mCalculatedCells.Remove 1 
     Range("A1").Value = 122333 
    Loop 
    Application.Calculation = xlCalculationAutomatic 
    Application.ScreenUpdating = True 
    End Sub 
+2

+1这太难看了! – 2012-02-29 08:32:43

+0

@ Jean-FrançoisCorbett我同意。我错觉有人能够想象然后执行这个。虽然它确实显示出“无法完成”的危险。 – brettdj 2012-02-29 08:43:39

+2

+1 LOL。同意JFC! – 2012-03-01 09:18:03

0

它应该工作 - 试试这个

  1. 打开一个新的Excel表
  2. 创建一个新的宏
  3. 添加此Sheets("Sheet1").Range("A1").Value2 = "value"

您可以同时使用.Value.Value2,确保表格名称是正确的。

+0

当我调试时,我停下了声明“Sheets(”Sheet1“)。Range(”A1“).Value2 =”。我不知道为什么? – Davuz 2012-02-28 06:13:41

+0

工作表的名称是什么,如果它不是'Sheet1',那么问题就来了..试试这个,而不是'Sheets(1).Range(“A1”).value',索引将有助于找到正确的工作表,一旦这个工作,你可以用实际的表名替换索引。 – 2012-02-28 06:30:48

+0

@Davuz:你的意思是“停止”?它会抛出任何错误吗?工作簿是否只读? – shahkalpesh 2012-02-28 07:18:06

5

您无法使用B2中的功能更改单元格A1。

访问:Description of limitations of custom functions in Excel 。该文本包括:

“的工作表单元格中的公式调用无法改变的Microsoft Excel环境中的用户定义函数这意味着此类函数不能做任何以下内容:

  • 插入,删除或格式细胞在电子表格上。
  • 更改另一单元格的值。 [我高亮]
  • 移动,重命名,删除或添加片材的工作簿。
  • 更改任何环境邻如计算模式或屏幕视图。
  • 将名称添加到工作簿。
  • 设置属性或执行大多数方法。”

你为什么要改变这样的单元格A1?解释你的目标,也许有人可以提供帮助。

+0

它实际上可以做到,但它很复杂。请参阅http://stackoverflow.com/q/8520732/641067 – brettdj 2012-02-28 10:01:10

+1

@brettdj。我错过了这个问题,你的回答非常有趣。但是,这不是我想推荐给新手的技术。我认为这是一个提问者告诉我们他是如何认为他的问题可以解决的问题,而不是他的问题。我想知道他为什么想要B2中的一个功能来改变A1? – 2012-02-28 11:09:21

+0

@TonyDallimore我想要缓存值。假设我计算非常多单元格的总和'范围(B1:B1000)',我希望将此总和值缓存到A1(或任何单元格),所以我重新打开excel文件,excel不需要重新计算 – Davuz 2012-02-29 02:09:19

1

如果要修改两个小区一个公式,你可能想考虑从你的函数返回一个数组,下面是一个例子:

Function abb() 
    Dim arr As Variant 
    ReDim arr(1 To 2) 
    arr(1) = "aardvark" 
    arr(2) = "bee" 
    abb = arr 
End Function 

选择单元格A2到B2。键入=abb()并按ShiftCtrl输入以指定它是数组公式。该公式然后同时修改两个单元格(A2和B2)。

也许你可以自定义这个来做你想做的事。

相关问题