5,172
社区成员




Excel文件中有两个工作表:来料明细和生产需求,要求用VBA编程判断来料明细中的物料到厂日期和数量能否满足生产需求,并在相应的列中回复,具体要求如下:
1.通过生产需求工作表中的缺料料号在来料明细工作表中进行查找相应的来料日期、来料数量。
2.将上一步中搜索的结果在生产需求工作表中进行反馈:E列输入到厂日期、F列可分配数量、若能满足生产则在G列输入“”OK“”,否则输入“”NO“”
3.若来料明细中未查到料号,则在生产需求工作表中E列~G列输入“”待确认“”
求大佬帮忙写个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
二、相关书籍推荐
Worksheet
和Range
对象的操作一样。推荐书籍 | 图书特点 |
---|---|
《Excel VBA编程入门》 | 作者:John Walkenbach,出版社:Wiley,适合小白阅读,以大量实例讲解VBA基础知识,涵盖变量、数据类型、控制结构等核心概念,但内容对有经验者可能不够深入 |
《Excel 2019 VBA宏编程从入门到精通》 | 作者:Michael Alexander,出版社:Packt Publishing,不仅包含基础知识,还深入探讨多工作表和工作簿数据交互、代码性能优化和错误处理等实用内容,但部分章节对初学者较难理解 |
《精通Excel VBA:职场办公高效应用》 | 作者:管文蔚,出版社:清华大学出版社,结合职场场景讲解VBA应用,对数组、自定义函数等高级特性讲解详细,但对零基础读者入门较难 |
有人接单了吗,没有的话吗,我来
在CSDN社区的帖子中,用户请求帮助编写一个VBA程序,用于在Excel中根据“来料明细”工作表中的物料到厂日期和数量来判断是否能满足“生产需求”工作表中的需求,并在相应的列中给出反馈。
以下是一个简单的VBA示例代码,用于实现用户的需求:
Sub CheckMaterialAvailability()
Dim wsIncoming As Worksheet
Dim wsProduction As Worksheet
Dim incomingRng As Range
Dim productionRng As Range
Dim incomingCell As Range
Dim materialCode As String
Dim incomingDate As Date
Dim incomingQty As Double
Dim requiredQty As Double
Dim i As Long
' 设置工作表
Set wsIncoming = ThisWorkbook.Sheets("来料明细")
Set wsProduction = ThisWorkbook.Sheets("生产需求")
' 生产需求的数据范围
Set productionRng = wsProduction.Range("A2:A" & wsProduction.Cells(Rows.Count, "A").End(xlUp).Row)
' 遍历生产需求中的每个料号
For Each productionCell In productionRng
materialCode = productionCell.Value
requiredQty = productionCell.Offset(0, 1).Value ' B列是需求量
' 在来料明细中查找对应的料号
Set incomingRng = wsIncoming.Range("A:A") ' 假设料号在第A列
For Each incomingCell In incomingRng
If incomingCell.Value = materialCode Then
incomingDate = incomingCell.Offset(0, 1).Value ' 假设到厂日期在B列
incomingQty = incomingCell.Offset(0, 2).Value ' 假设数量在C列
' 检查来料是否满足生产需求
If incomingQty >= requiredQty Then
productionCell.Offset(0, 4).Value = incomingDate ' E列是到厂日期
productionCell.Offset(0, 5).Value = incomingQty - requiredQty ' F列是可分配数量
productionCell.Offset(0, 6).Value = "OK" ' G列是状态
Else
productionCell.Offset(0, 4).Value = "待确认"
productionCell.Offset(0, 5).Value = incomingQty
productionCell.Offset(0, 6).Value = "NO"
End If
Exit For
End If
Next incomingCell
' 如果在来料明细中未找到料号
If incomingCell.Address = incomingRng.Cells(1, 1).Address Then
productionCell.Offset(0, 4).Value = "待确认"
productionCell.Offset(0, 5).Value = "待确认"
productionCell.Offset(0, 6).Value = "待确认"
End If
Next productionCell
MsgBox "检查完成!"
End Sub
使用说明:
CheckMaterialAvailability
宏。请注意,这个代码是一个基本的实现,可能需要根据你的具体Excel文件结构进行调整。例如,你可能需要根据实际的列位置调整Offset
方法中的参数。此外,这个代码假设“来料明细”工作表中的料号是唯一的,如果存在多个相同的料号,可能需要进一步的逻辑来处理这种情况。
两个表的料号和日期关联相等再去判断数量是否满足吗?
我和楼上的思路是一样的,简单的函数就能满足啊,你每次生产需求表只清空前三列不就行了吗?E-G列公式保留
用函数就可以了,上传附件吧