Microsoft VBA Excel VBA函数学习笔记——数据切分熟练度+1

问题场景

123456
Stock006006006002002002
MarketUSUSUSUSUSUS
Weight0.010.1090.2280.2220.2390.72
CurrencyEURUSDCNYEURUSDCNY
Term10.0740.0820.0120.0470.0580.067
Term20.040.020.010.070.0580.067
Term30.0540.0520.0140.0870.0480.017
Term40.0710.0840.0020.0170.0180.097

函数接收六个参数,包括工作簿地址和sheet名称等。函数将会根据指定的StockMarket来筛选数据,并将特定的Currency数据复制到目标工作簿的相应位置。同时,会把对应的Weight值存储到另一个目标sheet中。

草稿版本1:

Function UpdateRatesAndWeights(sourceWorkbookPath As String, sourceSheetName As String, _
                               ByVal wsTarget As Worksheet, ByVal wsRun As Worksheet, _
                               selectedStock As String, selectedMarket As String)
    Dim wbSource As Workbook
    Dim wsSource As Worksheet
    Dim lastRow As Long, lastColumn As Long
    Dim r As Long, c As Long
    Dim startRow As Long, endRow As Long, startColumn As Long, endColumn As Long
    Dim currencyColumn As Integer
    Dim weightRange As Range, termRange As Range
    Dim targetRow As Long
    Dim currencyCode As String
    Dim weightName As String
    
    ' 打开源工作簿
    Set wbSource = Workbooks.Open(sourceWorkbookPath)
    Set wsSource = wbSource.Sheets(sourceSheetName)
    
    ' 获取数据的总行数和列数
    lastRow = wsSource.Cells(wsSource.Rows.Count, 1).End(xlUp).Row
    lastColumn = wsSource.Cells(1, wsSource.Columns.Count).End(xlToLeft).Column
    
    ' 找到符合条件的数据行列范围
    For c = 1 To lastColumn
        If wsSource.Cells(1, c).Value = selectedStock And wsSource.Cells(2, c).Value = selectedMarket Then
            If startColumn = 0 Then
                startColumn = c
            End If
            endColumn = c
        End If
    Next c
    
    ' 设置Term行的起止
    startRow = 4  ' 假设Term数据从第4行开始
    endRow = 102  ' 假设Term数据到第102行 (共99个Term)
    
    ' 逐一复制Currency对应的数据
    For c = startColumn To endColumn
        currencyCode = wsSource.Cells(3, c).Value  ' Currency数据在第3行
        targetRow = wsTarget.Cells(wsTarget.Rows.Count, 1).End(xlUp).Row + 1
        
        ' 复制数据到指定的Currency区域
        Set termRange = wsSource.Range(wsSource.Cells(startRow, c), wsSource.Cells(endRow, c))
        termRange.Copy Destination:=wsTarget.Cells(targetRow, wsTarget.Range(currencyCode).Column)
        
        ' 复制Weight值
        weightName = "weight_" & currencyCode
        wsRun.Range(weightName).Value = wsSource.Cells(3, c).Offset(1, 0).Value  ' 假设Weight在Currency下面一行
    Next c
    
    ' 关闭源工作簿
    wbSource.Close SaveChanges:=False
End Function

缺陷:

  • 函数假设CurrencyWeight数据的位置是固定的。如果位置有所不同,需要调整代码中的相关部分。
  • 确保目标工作簿中有准确命名的命名区域,如EURUSDCNY以及weight_EUR等。
  • 缺少错误处理、异常捕捉和更复杂的数据验证。

为了提高代码的精确性和通用性,我
可以加入一些功能,比如动态查找CurrencyWeight的列位置,以及更加详细的错误处理。这样的改进可以让函数更加健壮,也能适应更多变的数据布局。

草稿版本2:

Function UpdateRatesAndWeights(sourceWorkbookPath As String, sourceSheetName As String, _
                               ByVal wsTarget As Worksheet, ByVal wsRun As Worksheet, _
                               selectedStock As String, selectedMarket As String)
    Dim wbSource As Workbook
    Dim wsSource As Worksheet
    Dim lastRow As Long, lastColumn As Long
    Dim r As Long, c As Long
    Dim startRow As Long, endRow As Long, startColumn As Long, endColumn As Long
    Dim currencyColumn As Integer
    Dim weightRange As Range, termRange As Range
    Dim targetRow As Long
    Dim currencyCode As String
    Dim weightName As String
    Dim currencyColumnMap As Object
    
    ' 使用字典来映射Currency与列号
    Set currencyColumnMap = CreateObject("Scripting.Dictionary")
    
    ' 打开源工作簿
    Set wbSource = Workbooks.Open(sourceWorkbookPath)
    Set wsSource = wbSource.Sheets(sourceSheetName)
    
    ' 获取数据的总行数和列数
    lastRow = wsSource.Cells(wsSource.Rows.Count, 1).End(xlUp).Row
    lastColumn = wsSource.Cells(1, wsSource.Columns.Count).End(xlToLeft).Column
    
    ' 找到符合条件的数据行列范围
    For c = 1 To lastColumn
        If wsSource.Cells(1, c).Value = selectedStock And wsSource.Cells(2, c).Value = selectedMarket Then
            currencyCode = wsSource.Cells(3, c).Value
            currencyColumnMap(currencyCode) = c
        End If
    Next c
    
    ' 设置Term行的起止
    startRow = 4  ' 假设Term数据从第4行开始
    endRow = 102  ' 假设Term数据到第102行 (共99个Term)
    
    ' 逐一复制Currency对应的数据
    For Each currencyCode In currencyColumnMap.Keys
        c = currencyColumnMap(currencyCode)
        targetRow = wsTarget.Cells(wsTarget.Rows.Count, 1).End(xlUp).Row + 1
        
        ' 复制数据到指定的Currency区域
        Set termRange = wsSource.Range(wsSource.Cells(startRow, c), wsSource.Cells(endRow, c))
        termRange.Copy Destination:=wsTarget.Cells(targetRow, wsTarget.Range(currencyCode).Column)
        
        ' 复制Weight值
        weightName = "weight_" & currencyCode
        wsRun.Range(weightName).Value = wsSource.Cells(3, c).Offset(1, 0).Value  ' 假设Weight在Currency下面一行
    Next currencyCode
    
    ' 关闭源工作簿
    wbSource.Close SaveChanges:=False
End Function

改进点说明:

  1. 使用字典:使用字典(Scripting.Dictionary)来存储每种Currency及其对应的列号。这样可以更灵活地处理不同Currency的位置,而不是硬编码列号。

  2. 动态处理:函数现在可以动态地处理不同的StockMarket组合,并且可以适应Currency列位置的变化。

总结

仍存在缺陷,稍后会更新

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值