VBA中返回数组的函数

2024-04-19

我是一名会计师,我需要每天将每笔客户付款与未清发票进行匹配,我在这个网站上发现了 Michael Schwimmer 发布的非常漂亮和优雅的 VBA 代码。https://berndplumhoff.gitbook.io/sulprobil/excel/excel-vba-solutions/accounts-receivable-problem https://berndplumhoff.gitbook.io/sulprobil/excel/excel-vba-solutions/accounts-receivable-problem

该代码运行完美,它可以自动计算并列出加起来达到特定总和的结果。但是,我希望 VBA 代码也返回发票号码。该代码将值的数组传递给函数进行计算,然后将可能的解决方案返回到 E 列,我对数组没有了解,所以不知道如何将发票号码的数组传递给函数并返回结果。有人可以帮忙吗?代码如下,您也可以从以下地址下载excel工作簿link https://berndplumhoff.gitbook.io/sulprobil/excel/excel-vba-solutions/accounts-receivable-problem我提供的。提前致谢!

Private Sub cmbCalculate_Click()

    Dim dGoal As Double
    Dim dTolerance As Double
    Dim dAmounts() As Double
    Dim vResult As Variant
    Dim m As Long
    Dim n As Long
    
With Me
   
    dGoal = .Range("B2")
    dTolerance = .Range("C2")
    ReDim dAmounts(1 To 100)
    For m = 2 To 101
    If (.Cells(m, 1) <> "") And (IsNumeric(.Cells(m, 1))) Then
        dAmounts(m - 1) = .Cells(m, 1)
    Else
        ReDim Preserve dAmounts(1 To m - 1)
        Exit For
    End If
    Next
    ReDim Preserve dAmounts(1 To UBound(dAmounts) - 1)

    vResult = Combinations(dAmounts, dGoal, dTolerance)
    Application.ScreenUpdating = False
    .Range("D3:D65536").ClearContents
    .Range(.Cells(3, 4), .Cells(UBound(vResult) + 3, 4)) = vResult
    Application.ScreenUpdating = True

End With

End Sub

Function Combinations( _
   Elements As Variant, _
   Goal As Double, _
   Optional Tolerance As Double, _
   Optional SoFar As Variant, _
   Optional Position As Long) As Variant
  
Dim i As Long
Dim k As Long
Dim dCompare As Double
Dim dDummy As Double
Dim vDummy As Variant
Dim vResult As Variant

If Not IsMissing(SoFar) Then

   'Sum of elements so far
   For Each vDummy In SoFar
      dCompare = dCompare + vDummy
   Next
  
Else

   'Start elements sorted by amount
   For i = 1 To UBound(Elements)
       For k = i + 1 To UBound(Elements)
           If Elements(k) < Elements(i) Then
               dDummy = Elements(i)
               Elements(i) = Elements(k)
               Elements(k) = dDummy
           End If
       Next
   Next
  
   Set SoFar = New Collection
  
End If

If Position = 0 Then Position = LBound(Elements)
For i = Position To UBound(Elements)

   'Add current element
   SoFar.Add Elements(i)
   dCompare = dCompare + Elements(i)
  
   If Abs(Goal - dCompare) < (0.001 + Tolerance) Then
  
      'Goal achieved
      k = 0
      ReDim vResult(0 To SoFar.Count - 1, 0)
      For Each vDummy In SoFar
         vResult(k, 0) = vDummy
         k = k + 1
      Next
      Combinations = vResult
      Exit For
     
   ElseIf dCompare < (Goal + 0.001 + Tolerance) Then
      'Enough room for another element
      'Call recursively starting with next higher amount
      vResult = Combinations(Elements, Goal, Tolerance, SoFar, i + 1)
      If IsArray(vResult) Then
         Combinations = vResult
         Exit For
      Else
         SoFar.Remove SoFar.Count
         dCompare = dCompare - Elements(i)
      End If
     
   Else
  
      'Amount too high
      SoFar.Remove SoFar.Count
      Exit For
     
   End If
  
Next 'Try next higher amount

End Function

您可能可以简单地使用 VLOOKUP 获取发票号码,但这里有一个 VBA 解决方案。我已经更改了中的值Sofar从发票金额收集到该金额的索引号。然后,该索引号给出新数组中相应的发票号InvNo.

更新 - 按截止日期排序

Sub cmbCalculate_Click()

    Dim ws As Worksheet, dAmounts() As Double, sInvno() As String
    Dim i As Long, dSum As Double
    Dim dtDue() As Date
   
    Set ws = Me
    i = ws.Cells(Rows.Count, "A").End(xlUp).Row
    ReDim dAmounts(1 To i - 1)
    ReDim sInvno(1 To i - 1)
    ReDim dtDue(1 To i - 1)

   ' fill array
    For i = 1 To UBound(dAmounts)
        dAmounts(i) = ws.Cells(i + 1, "A")
        sInvno(i) = ws.Cells(i + 1, "B")
        dtDue(i) = ws.Cells(i + 1, "C")
        dSum = dSum + dAmounts(i)
    Next
    ' sort array
    Call BubbleSort(dAmounts, sInvno, dtDue)
    Dim n: For n = LBound(dAmounts) To UBound(dAmounts): Debug.Print n, dAmounts(n), sInvno(n), dtDue(n): Next

    Dim dGoal As Double, dTolerance As Double, vResult As Variant
    dGoal = ws.Range("D2")
    dTolerance = ws.Range("E2")

    ' check possible
    If dGoal > dSum Then
         MsgBox "Error : Total for Invoices " & Format(dSum, "#,##0.00") & _
         " is less than Goal " & Format(dGoal, "#,##0.00")
    Else
        ' solve and write to sheet
        vResult = Combinations2(dAmounts, sInvno, dtDue, dGoal, dTolerance)
        If IsArray(vResult) Then
            With ws
                .Range("F3:H" & Rows.Count).ClearContents
                .Range("F3").Resize(UBound(vResult), 3) = vResult
            End With
            MsgBox "Done"
        Else
            MsgBox "Cannot find suitable combination", vbCritical
        End If
     End If

End Sub


Function Combinations2( _
    Elements As Variant, _
    Invno As Variant, _
    Due As Variant, _
    Goal As Double, _
    Optional Tolerance As Double, _
    Optional SoFar As Variant, _
    Optional Position As Long) As Variant

    Dim i As Long, n As Long, dCompare As Double

    ' summate so far
    If IsMissing(SoFar) Then
        Set SoFar = New Collection
    Else
        For i = 1 To SoFar.Count
            dCompare = dCompare + Elements(SoFar(i))
        Next
    End If

    If Position = 0 Then Position = LBound(Elements)
    For i = Position To UBound(Elements)

        SoFar.Add CStr(i)
        dCompare = dCompare + Elements(i)

        ' check if target achieved
        If Abs(Goal - dCompare) < (0.001 + Tolerance) Then

            'Goal achieved
            Dim vResult As Variant
            ReDim vResult(1 To SoFar.Count, 1 To 3)
            For n = 1 To SoFar.Count
               vResult(n, 1) = Elements(SoFar(n))
               vResult(n, 2) = Invno(SoFar(n))
               vResult(n, 3) = Due(SoFar(n))
            Next
            Combinations2 = vResult
    
        ElseIf dCompare < (Goal + 0.001 + Tolerance) Then
            'Enough room for another element
            'Call recursively starting with next higher amount
            vResult = Combinations2(Elements, Invno, Due, Goal, Tolerance, SoFar, i + 1)
            If IsArray(vResult) Then
                 Combinations2 = vResult
                 Exit For
            Else
                 SoFar.Remove SoFar.Count
                 dCompare = dCompare - Elements(i)
            End If
        Else
      
            'Amount too high
            SoFar.Remove SoFar.Count
            Exit For
       End If
    Next
End Function

Sub BubbleSort(ByRef ar1 As Variant, ByRef ar2 As Variant, ByRef ar3 As Variant)
   ' sort both arrays
   Dim d, s, i As Long, k As Long, dt As Date
   For i = 1 To UBound(ar1)
       For k = i + 1 To UBound(ar1)
           If (ar1(k) < ar1(i)) Or _
              (ar1(k) = ar1(i) _
           And ar3(k) < ar3(i)) Then
               d = ar1(i)
               ar1(i) = ar1(k)
               ar1(k) = d
               s = ar2(i)
               ar2(i) = ar2(k)
               ar2(k) = s
               dt = ar3(i)
               ar3(i) = ar3(k)
               ar3(k) = dt
           End If
       Next
   Next
End Sub
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VBA中返回数组的函数 的相关文章

  • 如何在Conky中实现一个基本的Lua功能?

    我正在尝试向我的 Conky 添加一个函数 该函数打印字符串的长度以用于调试目的 代码位于名为的文件内test lua 非常简单 function test word return string len word end 我这样加载它 在我
  • 如何使用 React 传递自定义服务器主机名?

    我希望能够在运行 React 应用程序时传递自定义服务器主机名 以便在需要获取数据时在 URL 中使用 服务器当前正在我的本地计算机上运行 因此当我使用获取 我一直在使用 http localhost 效果非常好 但我希望能够传递要在 UR
  • C# 计算 int 数组中值的平均值

    当我尝试打印 int 数组中的值的平均值时 它会打印出与我有值一样多的完全不同的东西 这是什么问题 int numbers numbers new int 5 Console WriteLine give five integer numb
  • 如何避免在 Excel 中垂直合并单元格?

    我厌倦了合并单元格 它们就是行不通 因此 当我只需要文本在多列中居中时 我找到了一种避免水平合并单元格的方法 那是 Range A1 C1 HorizontalAlignment xlCenterAcrossSelection 它就像一个魅
  • 展平数组中的对象

    大家好 我从响应中获取了一系列对象 我需要将所有学生对象展平为简单的学生姓名 但不确定如何进行 任何帮助将不胜感激 数组示例 students id 123456 name Student Name active true students
  • usort 不适用于 laravel 多维数组

    我有一个数组 Illuminate Support Collection Object items protected gt Array 0 gt stdClass Object id gt 79 name gt shelin status
  • 如何使“new[]”默认初始化原始类型数组?

    我时不时需要打电话new 对于内置类型 通常char 结果是一个具有未初始化值的数组 我必须使用memset or std fill 来初始化元素 我该如何制作new 默认初始化元素 int p new int 10 应该做 然而 作为迈克
  • 如何在 VBA 中的 Outlook-2007 中获取“已发送邮件”文件夹中的邮件 ID 或标头

    这是这个问题的一个子问题main https stackoverflow com questions 14418643 in ms outlook report all sent messages that havent received
  • 领域对象返回 nil (Swift)

    我有一个自定义多边形对象 因此我可以将地图叠加保存到领域 我能够成功创建这个对象 但是当我想检索 var 多边形对象时 它返回 nil 当我打印多边形对象时 它可以很好地打印出所有数据 这是打印内容的示例 CustomPolygon nam
  • ruby 1.9 如何将数组转换为不带括号的字符串

    我的问题是关于如何在 ruby 1 9 中将数组元素转换为字符串而不需要括号和引号 我有一个数组 数据库提取 我想用它来创建定期报告 myArray Apple Pear Banana 2 15 12 在 ruby 1 8 中我有以下行 r
  • JavaScript 调用函数

    我最近一直在测试一些代码 试图更好地理解 javascript 然后我遇到了call 我无法很好地理解的功能 我有以下代码 function hi console log hi var bye function param param2 c
  • Powershell逐字读取文本文件

    因此 我试图计算文本文件的单词数 但是当我执行 get content 时 数组会逐个字母地读取它们 因此它不允许我逐个单词地比较它们 我希望你们能帮助我 清除主机 功能 function Get Articles foreach Word
  • C# 中的字符串数组

    我在字符串数组中插入字符串元素时遇到问题 例如 我有三个赋值行 a b b c c e 然后我想将这六个变量插入string 变量 我使用以下代码 但此代码仅插入最后一个赋值变量 c e for int i 0 i lt S i S 3 n
  • Excel VBA 中的正则表达式

    我在 Excel VBA 中使用 Microsoft 正则表达式引擎 我对正则表达式很陌生 但我现在有一个正在运行的模式 我需要扩展它 但我遇到了麻烦 到目前为止 这是我的代码 Sub ImportFromDTD Dim sDTDFile
  • 将数组内爆为来自 mysql 查询的逗号分隔字符串

    在过去的 1 1 2 天里 我一直在尝试将 16 行 id 存储到一个字符串中 并用逗号分隔每个 id 我得到的数组来自 MySQL 我得到的错误是 implode 函数 传递了无效参数 str array string while row
  • 将带有非字符串关键字的 dict 传递给 kwargs 中的函数

    我使用具有签名功能的库f args kwargs 我需要在 kwargs 参数中传递 python dict 但 dict 不包含关键字中的字符串 f 1 2 3 4 Traceback most recent call last File
  • Java ArrayList,在一行中获取多种类型(int、String 等)的用户输入

    我正在努力提高 Java 水平 我遇到的一个问题是获取用户输入 所有这些都在一行中 如下所示 System out println Please input numbers that you would like to work with
  • 带条件的 Array.join()

    我该如何使用Array join 有条件的函数 例如 var name aa bb var s name join 输出是 aa bb 我想添加一个条件 仅显示不为空的单词 aa bb 您可以使用Array filter https dev
  • 更新 SQL MS Access 2010

    这已经让我绞尽脑汁了 4 个小时了 我有一个名为 BreakSked 的表 我使用此按钮来使用此 sql 更新表的休息结束时间 strSQL1 UPDATE BreakSked SET BreakSked EndTime Me Text41
  • 如何将 typedef 结构传递给函数?

    此刻我正在努力 void avg everything 但这给了我错误 error subscripted value is neither array nor pointer 当我今天早些时候收到此错误时 这是 因为我没有正确地将 2D

随机推荐

  • JSON Marshal 结构,方法返回作为字段

    是否可以将方法返回作为字段封送结构 例如 我想要这个 JSON cards 1 2 3 value 6 size 3 有了这种结构 type Deck struct Cards int json cards Value func int j
  • SQL INSERT/SELECT 不在插入表中的地方

    INSERT INTO tableA SELECT Col1 Col2 NOW FROM tableB WHERE tableA Col1 is not already in tableB Col1 我无法正确使用 WHERE 子句来确保从
  • PHP foreach 循环外访问变量

    我是 PHP 新手 谁能告诉我如何访问 foreach 之外的 foreach 循环变量 请通过代码查找如下 我需要它在下面的 html img 标签的 src 属性中
  • 如何对来自 Alamofire 的 JSON 进行排序并返回最终的 JSON 对象 (swiftyJSON)

    我无法简洁地从 api 提取数据 将用户当前位置添加到对象中 然后根据计算出的距离对数据进行排序 stackoverflow 的问题并不能完全回答我面临的问题 看这里 如何在 Swift 中对从 JSON 服务器文件读取的帖子进行排序 ht
  • golang 交换两个数字

    我正在尝试了解 Go 的内部结构 考虑下面的代码 a b 10 5 b a a b 上面的代码完美地交换了 2 个数字 a 变成了 5 b 变成了 10 我无法理解这是如何工作的 考虑到第二行代码 如果a先分配给b 那么b将是10 现在 如
  • 使用 Spring MVC 和 ajax 返回字符串时编码错误

    我有一个网页 使用 Ajax 请求希伯来语字符串 但该字符串返回为 奇怪的是 当使用 JSTL 而不是 Ajax 将相同的字符串插入页面时 它会正确显示 在我的网页中我声明 那是我的控制器 RequestMapping get label
  • 在 Ruby 中获取 URL 的重定向

    根据 Facebook 图形 API 我们可以使用以下命令请求用户个人资料图片 示例 https graph facebook com 1489686594 picture 但上一个链接的真实图片URL是 http profile ak f
  • 阅读 R Shiny DT 数据表中长文本的更多按钮

    我想在我的 R Shiny DT 数据表中包含 阅读更多 和 阅读更少 按钮 用于具有溢出 长文本的单元格 这个精彩的答案 https stackoverflow com a 51242920 4892627作者 Devansh J 在纯
  • Spring Security 4.2 中的 StrictHttpFirewall 与 Spring MVC @MatrixVariable

    升级到 spring security 4 2 4 后 我发现 StrictHttpFirewall 现在是默认的 不幸的是 它不能与 spring MVC MatrixVariable 很好地配合 因为 不再允许 如何解决这个问题 Exa
  • kSystemSoundID_Vibrate 不适用于 AVAudioPlayer Play

    我正在开发一个半双工 VOIP 呼叫应用程序 因为我试图在楼层交换期间播放音调和振动 进行楼层交换是将讲话者从 A 更改为 B 或者反之亦然 以进行半双工呼叫 如果我尝试使用 AudioServicesPlayAlertSound 播放提示
  • Django,从模型方法进行查询过滤

    我有这些模型 def Foo Models model size models IntegerField other fields def is active self if check condition return True else
  • 渲染空中继器

    When Repeater不包含任何项目 它根本不会以 HTML 形式呈现 甚至HeaderTemplate or FooterTemplate 即使它是空的 我也需要在客户端操作它 有没有办法始终在 HTML 中呈现 Repeater I
  • 使用 SendKeys.Send() 模拟右 Shift+Ctrl

    I m trying to Send right Shift Ctrl to my RichTextBox But as default it sends the left keys SendKeys Send Is there anywa
  • 如何启动超过 16 个 Android 模拟器

    运行 16 个模拟器时 adb devices shows List of devices attached emulator 5584 emulator 5582 emulator 5580 emulator 5578 emulator
  • UPDATE的目标表不可更新

    我需要运行这个查询 UPDATE TempRH T JOIN SELECT offices id MAX Poids AS Poids FROM TempRH GROUP BY offices id T1 ON T1 offices id
  • 如何将 pandas Series 作为行而不是列写入 CSV?

    我需要写一个pandas Series对象将 CSV 文件视为行 而不是列 简单地做 the series to csv file csv 给了我一个这样的文件 record id 2013 02 07 column a 7 0 colum
  • 重置表单重置按钮上的 ckeditor 值

    我的表单上有一个表单重置按钮 a href class btn Reset a 这将重置表单上除 ckeditor 之外的所有控件 并且我希望能够重置表单上 ckeditor 的值 ckeditor 的关联文本区域被重置 那么我该如何将 c
  • 如何包含同一项目中另一个文件的模块?

    依照指示本指南 https doc rust lang org 0 12 0 guide html crates and modules我创建了一个 Cargo 项目 src main rs fn main hello print hell
  • 渲染 Markdown 文件时,标题不显示在 R Markdown 上

    我正在尝试将 Rmd 文件转换为 md 输出 md document 但标题未显示在渲染的文件上 当我尝试将同一文件渲染为 html 文件 输出 html document 时 标题确实会显示 标题显示在渲染的文档上 title Test
  • VBA中返回数组的函数

    我是一名会计师 我需要每天将每笔客户付款与未清发票进行匹配 我在这个网站上发现了 Michael Schwimmer 发布的非常漂亮和优雅的 VBA 代码 https berndplumhoff gitbook io sulprobil e