首页 文章

VBA中的特殊复制粘贴

提问于
浏览
0

这是使用VBA的复制粘贴问题 . 我基本上想从许多不同的工作簿中获取一个数字 . 我的问题是这个数字正在迅速更新,所以我认为如果不打开工作簿,我就不能拥有该数字的最后一个数字 . 工作簿很大,需要时间来打开和加载数据(从外部源(bloomberg)获取数据) . 我的第一个线索是打开工作簿,然后让他们收费,然后从中获取数据 . 我的问题是,我需要设置一个计时器来执行此操作(并让我的工作簿加载)并且在此计时器期间我的工作簿无法上传数据,因此我最终得到了我的旧数据...

所以我发现的唯一解决方案是做两个不同的宏 . 一个打开所有工作簿,然后第二个关闭并保存并从中获取数据...

你们有什么好主意吗?

我的问题是,工作簿是如此之大,我需要以5×5的最大值打开它们并且每次都这样做...

我复制粘贴你的代码,我知道这是非常基本的,如果你想到任何更好的代码或方法使它工作,请让我知道 .

Sub OpenWorkbooks()
workbooks.Open Filename :="C/.../file1.xlsx"
workbooks.Open Filename :="C/.../file2.xlsx"
workbooks.Open Filename :="C/.../file3.xlsx"
.
.
End sub

现在关闭然后复制粘贴其他人写的值 .

Sub GetNumber()
Dim wWbPath As String, WbName As String
Dim WsName As String, CellRef As String
Dim Ret As String


Workbooks("file1").Close SaveChanges:=True

wbPath = "C:/etc...."

WbName = "file1.xlsx"
WsName = "Sheet1"
CellRef = "AD30"


arg = "'" & wbPath & "[" & wbName & "]" & _ 
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1) 

Worksheets("Sheet1").Range("A1") = ExecuteExcel4Macro(arg) 

End sub

如上所述,您认为有更好的方法吗?我想为每个文件执行整个步骤,但我不能,因为计时器停止刷新我的spreadhseet,我需要一个计时器,因为我的工作表需要时间加载 . 所以1 - 打开全部,2-全部关闭并保存全部并复制数字...但是我需要批量处理,如果我打开所有崩溃...

我的另一个问题是,我怎样才能使代码变得更好?最后,我希望在我的开放式工作簿中有一个电子表格,我可以在其中打开并复制/粘贴每个worbook的所有路径 . 然后我想要一个循环路径的宏,打开工作簿等待(但计时器不工作......)然后复制粘贴并关闭 .

altrnative总是循环路径,但是通过块 . 我将所有路径放在单元格A1:A10上,我可以有一个循环打开A1:A10中的路径,然后第二个宏关闭并保存工作簿,路径为A1:A10

欢迎任何想法,

谢谢

2 回答

  • 1
    Sub testopenRefreshClose()
        Call openRefreshClose("C/.../file1.xlsx")
        Call openRefreshClose("C/.../file1.xlsx")
    End Sub
    Sub openRefreshClose(wbPathName As String)
        Dim wb As Workbook
    
        Set wb = Workbooks.Open(wbPathName) ' open and assign to workbook object
        wb.RefreshAll ' refresh the data
        wb.Close SaveChanges:=True ' close the workbook
    End Sub
    

    这似乎在关闭之前完成运行查询,但您也可以尝试取消选中启用后台刷新,这将确保在采取其他操作之前更新数据 .

    enter image description here

  • 1

    您可以通过不同方式实现这一目标 . 一种是将值存储在工作表或数据库中,每次要刷新并获取新值时,将新值与旧值进行比较,如果不同(单元格值确定更新),则继续执行代码 . 只是为了让代码不再等待你应该设置一个最长时间,就像一个到期时间 . 我会做20次迭代,每次5秒 . 所以基本上你应该在你的代码中有这样的设置:

    for i=1 to 20
        newHour = Hour(Now()) 
        newMinute = Minute(Now()) 
        newSecond = Second(Now()) + 5
        waitTime = TimeSerial(newHour, newMinute, newSecond) 
        ' ~~> get new value here and compare it to the old value
    
    next i
    
    Application.Wait waitTime
    
    
    if newValue<>oldValue then
        exit for
    else
        'do nothing, just wait
    end if
    

    或者你可以简单地让Windows控制,完成任务并继续:

    '~~> your code here before refresh
    Activeworkbook.RefreshAll
    DoEvents
    '~~> rest of your code here after refresh
    

    DoEvents 让Windows暂时从Macro中断处理所有待处理事件,然后再返回宏 . 这意味着它将从外部资源刷新您的工作簿,然后继续执行其余代码 .

    如果您使用的是Excel 2010及更高版本,则可以使用比DoEvents更好的控件:

    ThisWorkbook.RefreshAll 'or activeworkbook, choose as you need
     Application.CalculateUntilAsyncQueriesDone 'the code execution will halt here until the refresh job is done
    

相关问题