如何在保持表的公式的同时使用VBA更新Excel表

时间:2013-04-16 13:34:31

标签: excel vba

我有一个电子表格,它定义了几个Excel表格,其中包括使用源数据的源数据和函数。例如,名为MyTbl的表包含三个“源列”和一个公式列...

Part   Price  Qty  Extended Price
------ -----  ---  --------------
Shoe   5.50   10   =(MyTbl[[#ThisRow],[Price]])*(MyTbl[[#ThisRow],[Qty]])
...

必须定期将源列替换为CSV文件中的值,但公式列应保持不受影响。该文件类似于:

Shoe,5.65,98
Coat,12.65,223
...

如何在保持Excel表及其公式存在的同时“刷新”源列?我想在VBA中执行此操作,因为CSV文件没有一致的名称或路径。

提前致谢。

1 个答案:

答案 0 :(得分:1)

感谢Doug Glancy的建议。

原始问题涉及将.csv加载到listobject中。我最终将csv中的数据加载到新工作表上的listobject中。然后我能够将源列表对象合并到目标列表对象中,同时使用以下过程维护目标维护的其他列(和公式)。此过程清除不需要的数据,如果源包含的行少于目标,则删除行,复制数据,并调整列表对象的大小。

此解决方案中的假设
  - 源列表对象包含少于目标
的一些列数   - 两个列表对象都包含一个标题行(我没有测试任何多于一个标题行)

Private Sub CopyTableData(loSource As Excel.ListObject, loTarget As Excel.ListObject)
Dim lSourceRowCount As Long

With loTarget
    If .DataBodyRange.Rows.Count <> loSource.DataBodyRange.Rows.Count Then
        ' clear of target area should clear target num rows and source num columns
        .Range(.Cells(1,1).Address, .Cells(.DataBodyRange.Rows.Count, lSource.RefersToRange.Columns.Count)).Clear

        ' clear rows if source has less than target
        If .DataBodyRange.Rows.Count > loSource.DataBodyRange.Rows.Count Then
            For i = .DataBodyRange.Rows.Count To loSource.DataBodyRange.Rows.Count + 1 Step -1
                .DataBodyRange.Rows(i).Clear
            Next i
        End If

        ' resize list object
        lSourceRowCount = loSource.HeaderRowRange.Rows.Count + _ 
                          loSource.DataBodyRange.Rows.Count

        .Resize .Range.Cells(1).Resize(lSourceRowCount, .Range.Columns.Count)
    End If
    loSource.DataBodyRange.Copy .DataBodyRange.Cells(1)
End With

With loTarget If .DataBodyRange.Rows.Count <> loSource.DataBodyRange.Rows.Count Then ' clear of target area should clear target num rows and source num columns .Range(.Cells(1,1).Address, .Cells(.DataBodyRange.Rows.Count, lSource.RefersToRange.Columns.Count)).Clear ' clear rows if source has less than target If .DataBodyRange.Rows.Count > loSource.DataBodyRange.Rows.Count Then For i = .DataBodyRange.Rows.Count To loSource.DataBodyRange.Rows.Count + 1 Step -1 .DataBodyRange.Rows(i).Clear Next i End If ' resize list object lSourceRowCount = loSource.HeaderRowRange.Rows.Count + _ loSource.DataBodyRange.Rows.Count .Resize .Range.Cells(1).Resize(lSourceRowCount, .Range.Columns.Count) End If loSource.DataBodyRange.Copy .DataBodyRange.Cells(1) End With

再次感谢。