求大佬帮忙写个VBA

FerrariGTX 2024-07-26 06:11:18

 

Excel文件中有两个工作表:来料明细和生产需求,要求用VBA编程判断来料明细中的物料到厂日期和数量能否满足生产需求,并在相应的列中回复,具体要求如下:


1.通过生产需求工作表中的缺料料号在来料明细工作表中进行查找相应的来料日期、来料数量。


2.将上一步中搜索的结果在生产需求工作表中进行反馈:E列输入到厂日期、F列可分配数量、若能满足生产则在G列输入“”OK“”,否则输入“”NO“”

3.若来料明细中未查到料号,则在生产需求工作表中E列~G列输入“”待确认“”

求大佬帮忙写个VBA程序,万分感谢~

...全文
1417 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

以下是针对上述VBA需求的更详细解答:

一、VBA代码优化与详细解释

  1. 数据结构与变量定义

    • 在原始代码中,使用了Range类型的变量来遍历工作表中的数据。这是一种常见的方法,但可以进一步优化。例如,在查找来料明细中的料号时,可以使用字典(Dictionary)对象来提高查找效率。字典可以将料号作为键,对应的到厂日期和数量等信息作为值存储起来,这样在查找时就不需要遍历整个列。
    • 对于变量的命名,可以更加具有描述性。比如,将incomingCell改为incomingMaterialCellproductionCell改为productionDemandCell等,以提高代码的可读性。
  2. 逻辑完善

    • 原始代码假设料号是唯一的,但在实际应用中可能并非如此。如果来料明细中存在多个相同料号的记录,需要对代码进行调整。一种方法是,当找到一个匹配的料号时,继续查找该料号的其他记录,累加数量,并根据最早(或最晚,根据业务需求)的到厂日期来确定结果。
    • 关于日期的比较,原始代码没有明确体现与缺料日期的比较逻辑。如果要按照到厂日期不晚于缺料日期的原则进行判断,需要在代码中添加相应的日期比较语句。

以下是优化后的部分代码示例:

Sub CheckMaterialAvailabilityOptimized()
    Dim wsIncoming As Worksheet
    Dim wsProduction As Worksheet
    Dim incomingDict As Object
![配图](https://hunyuan-prod-1258344703.cos.ap-guangzhou.myqcloud.com/text2img/de4afd800048ccc92ecb6920a5a0fe3b/20250124030249h0_457a4603406fac38c4d89ff30cdd53a32a5.png?q-sign-algorithm=sha1&q-ak=AKIDRl074nOsGdJ9zjMsCRWP3ShmgS3VtX4S&q-sign-time=1737658969;1769194969&q-key-time=1737658969;1769194969&q-header-list=host&q-url-param-list=&q-signature=a6eaa50673fe301555edcd47832175b3080f139e)
    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)
![配图](https://hunyuan-prod-1258344703.cos.ap-guangzhou.myqcloud.com/text2img/de4afd800048ccc92ecb6920a5a0fe3b/20250124030249h0_319d704bb95034613377c44865cb9c0a87a.png?q-sign-algorithm=sha1&q-ak=AKIDRl074nOsGdJ9zjMsCRWP3ShmgS3VtX4S&q-sign-time=1737658969;1769194969&q-key-time=1737658969;1769194969&q-header-list=host&q-url-param-list=&q-signature=5bee4b9afcfdd1facf86939dfd978b6c8213b531)
                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
![配图](https://hunyuan-prod-1258344703.cos.ap-guangzhou.myqcloud.com/text2img/de4afd800048ccc92ecb6920a5a0fe3b/20250124030249h0_33420dfb1e1d23eca99a080f3dc97aee402.png?q-sign-algorithm=sha1&q-ak=AKIDRl074nOsGdJ9zjMsCRWP3ShmgS3VtX4S&q-sign-time=1737658969;1769194969&q-key-time=1737658969;1769194969&q-header-list=host&q-url-param-list=&q-signature=4c7867bc4966fabfd0a5653aed16def20048acb3)
                    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

二、相关书籍推荐

  1. 《Excel VBA编程入门》
    • 作者:John Walkenbach
    • 出版社:Wiley
    • 特点
      • 优点:
        • 这是一本非常适合初学者的VBA入门书籍。书中以大量的实例讲解VBA的基础知识,从基本的宏录制开始,逐步引导读者理解VBA的语法、对象模型等内容。例如,它会详细解释如何操作Excel中的工作表、单元格等对象,就像我们在解决上述问题时对WorksheetRange对象的操作一样。
        • 内容循序渐进,涵盖了变量、数据类型、控制结构(如条件判断、循环)等核心概念,并且每个知识点都有对应的代码示例和详细的解释。
      • 缺点:
        • 对于有一定经验的VBA开发者来说,可能会觉得某些内容过于基础,不够深入。例如在一些高级的数据处理和算法优化方面的讲解较少。
  2. 《Excel 2019 VBA宏编程从入门到精通》
    • 作者:Michael Alexander
    • 出版社:Packt Publishing
    • 特点
      • 优点:
        • 不仅讲解了VBA的基础知识,还深入探讨了一些在实际工作中常用的复杂任务,如在多个工作表和多个工作簿之间进行数据交互。这对于处理像我们之前提到的涉及“来料明细”和“生产需求”两个工作表的情况非常有帮助。
        • 提供了很多实用的技巧和最佳实践方法,比如如何优化VBA代码的性能,如何进行错误处理等。
      • 缺点:
        • 部分章节的内容比较紧凑,对于初学者来说可能理解起来有一定难度,需要有一定的耐心和基础知识储备。
  3. 《精通Excel VBA:职场办公高效应用》
    • 作者:管文蔚
    • 出版社:清华大学出版社
    • 特点
      • 优点:
        • 结合了大量的职场实际场景,使读者能够更好地理解如何将VBA应用到实际工作中。书中有很多关于数据处理、报表生成等方面的案例,与我们解决的生产需求和来料明细的场景类似。
        • 对VBA中的数组、自定义函数等高级特性有比较详细的讲解,可以帮助读者提升编写复杂VBA程序的能力。
      • 缺点:
        • 对于完全没有编程基础的读者,可能在入门阶段会觉得有些吃力,因为它的起点相对较高,没有像前两本书那样非常细致地从最基础的概念开始讲解。
推荐书籍图书特点
《Excel VBA编程入门》作者:John Walkenbach,出版社:Wiley,适合小白阅读,以大量实例讲解VBA基础知识,涵盖变量、数据类型、控制结构等核心概念,但内容对有经验者可能不够深入
《Excel 2019 VBA宏编程从入门到精通》作者:Michael Alexander,出版社:Packt Publishing,不仅包含基础知识,还深入探讨多工作表和工作簿数据交互、代码性能优化和错误处理等实用内容,但部分章节对初学者较难理解
《精通Excel VBA:职场办公高效应用》作者:管文蔚,出版社:清华大学出版社,结合职场场景讲解VBA应用,对数组、自定义函数等高级特性讲解详细,但对零基础读者入门较难

已隐藏部分内容,更多查看原文

学无止境s 2024-09-21
  • 打赏
  • 举报
回复

img

学无止境s 2024-09-21
  • 打赏
  • 举报
回复

有人接单了吗,没有的话吗,我来

Slingerspir 2024-08-25
  • 打赏
  • 举报
回复

在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") ' 假设料号在第AFor Each incomingCell In incomingRng
            If incomingCell.Value = materialCode Then
                incomingDate = incomingCell.Offset(0, 1).Value ' 假设到厂日期在BincomingQty = 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

使用说明:

  1. 将此代码复制到Excel VBA编辑器中。
  2. 确保你的工作表名称和列位置与代码中的假设相匹配,或者根据实际情况调整代码。
  3. 运行CheckMaterialAvailability宏。

请注意,这个代码是一个基本的实现,可能需要根据你的具体Excel文件结构进行调整。例如,你可能需要根据实际的列位置调整Offset方法中的参数。此外,这个代码假设“来料明细”工作表中的料号是唯一的,如果存在多个相同的料号,可能需要进一步的逻辑来处理这种情况。

jxzhoumin 2024-07-26
  • 打赏
  • 举报
回复

两个表的料号和日期关联相等再去判断数量是否满足吗?

FerrariGTX 2024-07-26
  • 举报
回复
@jxzhoumin 到厂日期不晚于缺料日期再去判断
德布德 2024-07-26
  • 打赏
  • 举报
回复

我和楼上的思路是一样的,简单的函数就能满足啊,你每次生产需求表只清空前三列不就行了吗?E-G列公式保留

德布德 2024-07-26
  • 举报
回复
@德布德 我想了下,按你说的要求。我觉得你可以直接手动全程操作一次,然后用录制宏把所有操作都录制下来,然后你每次粘贴完两张表后,点下你录制的宏,不就后面的就按你之前的操作自动执行一遍了么
lfspecter 2024-07-26
  • 打赏
  • 举报
回复 1

用函数就可以了,上传附件吧

FerrariGTX 2024-07-26
  • 举报
回复
@lfspecter 这两个工作表使用前都要清空,然后拷贝新的内容,用函数容易被一起清空,所以考虑VBA
jason_wa 01-20
  • 举报
回复
@FerrariGTX 可以去了解下excel中,有个另存为文件类型为“excel模板”的功能。

5,172

社区成员

发帖
与我相关
我的任务
社区描述
其他开发语言 Office开发/ VBA
社区管理员
  • Office开发/ VBA社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧