求大佬帮忙写个VBA
以下是针对上述VBA需求的更详细解答:
一、VBA代码优化与详细解释
-
数据结构与变量定义
- 在原始代码中,使用了Range
类型的变量来遍历工作表中的数据。这是一种常见的方法,但可以进一步优化。例如,在查找来料明细中的料号时,可以使用字典(Dictionary
)对象来提高查找效率。字典可以将料号作为键,对应的到厂日期和数量等信息作为值存储起来,这样在查找时就不需要遍历整个列。
- 对于变量的命名,可以更加具有描述性。比如,将incomingCell
改为incomingMaterialCell
,productionCell
改为productionDemandCell
等,以提高代码的可读性。 -
逻辑完善
- 原始代码假设料号是唯一的,但在实际应用中可能并非如此。如果来料明细中存在多个相同料号的记录,需要对代码进行调整。一种方法是,当找到一个匹配的料号时,继续查找该料号的其他记录,累加数量,并根据最早(或最晚,根据业务需求)的到厂日期来确定结果。
- 关于日期的比较,原始代码没有明确体现与缺料日期的比较逻辑。如果要按照到厂日期不晚于缺料日期的原则进行判断,需要在代码中添加相应的日期比较语句。
以下是优化后的部分代码示例:
Sub CheckMaterialAvailabilityOptimized() Dim wsIncoming As Worksheet Dim wsProduction As Worksheet Dim incomingDict As Object  Dim productionRng As Range Dim productionDemandCell As Range Dim materialCode As String Dim requiredQty As Double Dim incomingDate As Date Dim incomingQty As Double Set wsIncoming = ThisWorkbook.Sheets("来料明细") Set wsProduction = ThisWorkbook.Sheets("生产需求") Set incomingDict = CreateObject("Scripting.Dictionary") '将来料明细中的数据存入字典 For Each incomingCell In wsIncoming.Range("A:A") If incomingCell.Value <> "" Then materialCode = incomingCell.Value If Not incomingDict.Exists(materialCode) Then incomingDict.Add materialCode, Array(incomingCell.Offset(0, 1).Value, incomingCell.Offset(0, 2).Value) Else Dim existingValues As Variant existingValues = incomingDict(materialCode)  incomingDict(materialCode) = ArrayWorksheetFunction.Min(existingValues(0), incomingCell.Offset(0, 1).Value), existingValues(1)+incomingCell.Offset(0, 2).Value) End If End If Next incomingCell '遍历生产需求工作表 Set productionRng = wsProduction.Range("A2:A" & wsProduction.Cells(Rows.Count, "A").End(xlUp).Row) For Each productionDemandCell In productionRng materialCode = productionDemandCell.Value requiredQty = productionDemandCell.Offset(0, 1).Value If incomingDict.Exists(materialCode) Then incomingDate = incomingDict(materialCode)(0) incomingQty = incomingDict(materialCode)(1) '假设缺料日期在C列,可根据实际情况调整 Dim shortageDate As Date shortageDate = productionDemandCell.Offset(0, 2).Value If incomingDate <= shortageDate Then If incomingQty >= requiredQty Then productionDemandCell.Offset(0, 4).Value = incomingDate  productionDemandCell.Offset(0, 5).Value = incomingQty - requiredQty productionDemandCell.Offset(0, 6).Value = "OK" Else productionDemandCell.Offset(0, 4).Value = incomingDate productionDemandCell.Offset(0, 5).Value = incomingQty productionDemandCell.Offset(0, 6).Value = "NO" End If Else productionDemandCell.Offset(0, 4).Value = "待确认" productionDemandCell.Offset(0, 5).Value = "待确认" productionDemandCell.Offset(0, 6).Value = "待确认" End If Else productionDemandCell.Offset(0, 4).Value = "待确认" productionDemandCell.Offset(0, 5).Value = "待确认" productionDemandCell.Offset(0, 6).Value = "待确认" End If Next productionDemandCell MsgBox "检查完成!" End Sub
二、相关书籍推荐
- 《Excel VBA编程入门》
- 作者:John Walkenbach
- 出版社:Wiley
- 特点- 优点:
- 这是一本非常适合初学者的VBA入门书籍。书中以大量的实例讲解VBA的基础知识,从基本的宏录制开始,逐步引导读者理解VBA的语法、对象模型等内容。例如,它会详细解释如何操作Excel中的工作表、单元格等对象,就像我们在解决上述问题时对
Worksheet
和Range
对象的操作一样。 - 内容循序渐进,涵盖了变量、数据类型、控制结构(如条件判断、循环)等核心概念,并且每个知识点都有对应的代码示例和详细的解释。
- 缺点:
- 对于有一定经验的VBA开发者来说,可能会觉得某些内容过于基础,不够深入。例如在一些高级的数据处理和算法优化方面的讲解较少。
- 《Excel 2019 VBA宏编程从入门到精通》
- 作者:Michael Alexander
- 出版社:Packt Publishing
- 特点- 优点:
- 不仅讲解了VBA的基础知识,还深入探讨了一些在实际工作中常用的复杂任务,如在多个工作表和多个工作簿之间进行数据交互。这对于处理像我们之前提到的涉及"来料明细"和"生产需求"两个工作表的情况非常有帮助。
- 提供了很多实用的技巧和最佳实践方法,比如如何优化VBA代码的性能,如何进行错误处理等。
- 缺点:
- 部分章节的内容比较紧凑,对于初学者来说可能理解起来有一定难度,需要有一定的耐心和基础知识储备。
- 《精通Excel VBA:职场办公高效应用》
- 作者:管文蔚
- 出版社:清华大学出版社
- 特点- 优点:
- 结合了大量的职场实际场景,使读者能够更好地理解如何将VBA应用到实际工作中。书中有很多关于数据处理、报表生成等方面的案例,与我们解决的生产需求和来料明细的场景类似。
- 对VBA中的数组、自定义函数等高级特性有比较详细的讲解,可以帮助读者提升编写复杂VBA程序的能力。
- 缺点:
- 对于完全没有编程基础的读者,可能在入门阶段会觉得有些吃力,因为它的起点相对较高,没有像前两本书那样非常细致地从最基础的概念开始讲解。
推荐书籍 | 图书特点 |
---|---|
《Excel VBA编程入门》 | 作者:John Walkenbach,出版社:Wiley,适合小白阅读,以大量实例讲解VBA基础知识,涵盖变量、数据类型、控制结构等核心概念,但内容对有经验者可能不够深入 |
《Excel 2019 VBA宏编程从入门到精通》 | 作者:Michael Alexander,出版社:Packt Publishing,不仅包含基础知识,还深入探讨多工作表和工作簿数据交互、代码性能优化和错误处理等实用内容,但部分章节对初学者较难理解 |
《精通Excel VBA:职场办公高效应用》 | 作者:管文蔚,出版社:清华大学出版社,结合职场场景讲解VBA应用,对数组、自定义函数等高级特性讲解详细,但对零基础读者入门较难 |
评论
发表评论