Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: zhxj1983

麻烦老师帮我做个条件查找返回值的宏

[复制链接]
发表于 2019-6-28 11:14 | 显示全部楼层
zhxj1983 发表于 2019-6-28 09:12
老师,J列这里,实棕规格有些怪,这里正常是规格才对的,但是有些奇怪又是3E棕加规格,那些有规格的,后 ...

1、J列的“3E棕加规格”是你源数据就是这样子的,“产品结构表”第62行;2、P\J组合颠倒的问题,你把这一行
    Cells(i, "q") = Cells(i, "j") & Cells(i, "p"),的单元格前后换个位置,改成

    Cells(i, "q") = Cells(i, "p") & Cells(i, "j"),应该就可以了。

    如果遇到其他类似列颠倒的问题,也是同样的方法修改,调换单元格的位置
回复

使用道具 举报

 楼主| 发表于 2019-6-28 11:33 | 显示全部楼层
hfwufanhf2006 发表于 2019-6-28 11:14
1、J列的“3E棕加规格”是你源数据就是这样子的,“产品结构表”第62行;2、P\J组合颠倒的问题,你把这一 ...

确实是的,麻烦老师你再替我看另一个贴子的那个产品进销存表的,那个你说的那种我比较能理解,麻烦你帮我把那个出库的那个表格用你说的方式,把代码写出来,我自己再看看,麻烦代码也稍微解释下。因为像这些是我们日常经常用到的
回复

使用道具 举报

 楼主| 发表于 2019-6-28 11:45 | 显示全部楼层
hfwufanhf2006 发表于 2019-6-28 11:14
1、J列的“3E棕加规格”是你源数据就是这样子的,“产品结构表”第62行;2、P\J组合颠倒的问题,你把这一 ...

那个相反的我改好了。像每次点这个按钮运行的话,能不能每次只查找后面新录入的行的数据,就是不再查找前面的了。比如这一次有80条记录,我点了这按钮后,这些信息出来了,然后我保存了。那么下次我再从81条可以录入新的订单的时候,再点这按钮的时候,就从这一行开始了,不要再去处理前面的那些数据了??因为有些匹配出来是空的话,我们会用人工来判定要用什么规格的材料来处理这些的,是手动录入进去的,手动操作的,如果这按钮又是从最初的行进行处理,就会把我前面一些手动处理的数据又改回来了这样
回复

使用道具 举报

发表于 2019-6-28 11:51 | 显示全部楼层
zhxj1983 发表于 2019-6-28 11:45
那个相反的我改好了。像每次点这个按钮运行的话,能不能每次只查找后面新录入的行的数据,就是不再查找前 ...

从技术角度,可以忽略已存在数据的单元格,这样设定后,只要单元格不是空白,就不会更新单元格已存在的内容;
但也会产生潜在的问题:如果你源数据有数据更新,那这些更新也不会被重新替换,因此你的要求只适用于源数据不会有再次更新的情况。如果你确认是这样的,我再修改。
回复

使用道具 举报

 楼主| 发表于 2019-6-28 12:05 | 显示全部楼层
hfwufanhf2006 发表于 2019-6-28 11:51
从技术角度,可以忽略已存在数据的单元格,这样设定后,只要单元格不是空白,就不会更新单元格已存在的内 ...

老师,你说的这个情况我知道的。一般我们如果后面改数据源的话,也只会从通知的那个时候起开始算的,前面的那些我们以前都是另外手工去处理的,不需要说把前面的这些全部要改成现在的,这种情况是非常少的,而且要改的,也只是一个数据源这样的,一般我们是查找筛选原来的这个,然后手工去替换前面的这些。
回复

使用道具 举报

发表于 2019-6-28 13:20 | 显示全部楼层
zhxj1983 发表于 2019-6-28 12:05
老师,你说的这个情况我知道的。一般我们如果后面改数据源的话,也只会从通知的那个时候起开始算的,前面 ...

我把代码全部更新一遍,后面还有说明:
Application.ScreenUpdating = False
Dim arr1(100, 2)
js = 0
For i = 60 To Worksheets("产品结构表").Range("h80").End(3).Row
    js = js + 1
    arr1(js, 1) = Worksheets("产品结构表").Cells(i, "h")
    arr1(js, 2) = Worksheets("产品结构表").Cells(i, "i")
Next i
Dim arr
arr = Worksheets("产品结构表").Range("a1:x" & Worksheets("产品结构表").[d10000].End(3).Row)
For i = 2 To [b10000].End(3).Row
    For k = 2 To UBound(arr)
        If (UCase(Cells(i, 6)) = UCase(arr(k, 13))) And IsEmpty(Cells(i, "i")) Then
           Cells(i, "i") = arr(k, 14)
        End If
        If (UCase(Cells(i, 4)) = UCase(arr(k, 1))) And IsEmpty(Cells(i, "j")) Then
           Cells(i, "j") = arr(k, 2)
        End If
        If (UCase(Cells(i, 5)) = UCase(arr(k, 4))) And IsEmpty(Cells(i, "k")) Then
           Cells(i, "k") = arr(k, 5)
           Cells(i, "p") = arr(k, 6)
        End If
        If (UCase(Cells(i, 4)) = UCase(arr(k, 16))) And IsEmpty(Cells(i, "l")) Then
           Cells(i, "l") = arr(k, 17)
           Cells(i, "m") = arr(k, 18)
        End If
   Next k
   If Not IsEmpty(Cells(i, "f")) Then
      bz = False
      For j = 1 To js
          If UCase(Cells(i, "f")) = UCase(arr1(j, 1)) Then
             bz = True
             jl = j
             Exit For
          End If
      Next j
      If bz Then
         Cells(i, "n") = arr1(jl, 2) & Cells(i, "l")
      Else
         Cells(i, "n") = Cells(i, "f") & Cells(i, "l")
      End If
   End If
   If Not IsEmpty(Cells(i, "i")) Then
      Cells(i, "o") = IIf(IsEmpty(Cells(i, "o")), Cells(i, "i") & Cells(i, "m"), Cells(i, "o"))
   End If
   If Not IsEmpty(Cells(i, "j")) Then
      Cells(i, "q") = IIf(IsEmpty(Cells(i, "q")), Cells(i, "p") & Cells(i, "j"), Cells(i, "q"))
   End If
Next i
Application.ScreenUpdating = True

说明:
1、只有空白的单元格才会更新数据:
     If (UCase(Cells(i, 6)) = UCase(arr(k, 13))) And IsEmpty(Cells(i, "i")) Then

        IsEmpty(Cells(i, "i"))表示此单元格是空白,后面的条件都类似
2、下列两种情况下:
    源数据做了大幅度更新;
    手工更新极少;
    可以通过人工删除J-O列的全部或部分内容来达到重新更新的目的,代码并不能区别哪些是人工更正的单元格,只要是空白的都会尝试去更新,因此你可以通过手工删除来控制空白单元格达到重新更新的目的。简单说就是你想更新哪个部分就把要更新的区域删掉就可以了;


回复

使用道具 举报

 楼主| 发表于 2019-6-28 14:18 | 显示全部楼层
hfwufanhf2006 发表于 2019-6-28 13:20
我把代码全部更新一遍,后面还有说明:
Application.ScreenUpdating = False
Dim arr1(100, 2)

老师做得很好,这非常达到我的要求,我看了,如果我后面自己手写了实棕规格,正面规格,背面规格之后,后面的那三列编码,有两列都能更新生成了,我看就只有一个背面编码不会,不过这应该不是什么大问题了。已经非常完美了
回复

使用道具 举报

发表于 2019-6-28 14:38 | 显示全部楼层
zhxj1983 发表于 2019-6-28 14:18
老师做得很好,这非常达到我的要求,我看了,如果我后面自己手写了实棕规格,正面规格,背面规格之后,后 ...

"有两列更新第三列不更新"是因为类似下面的条件存在:
If (UCase(Cells(i, 5)) = UCase(arr(k, 4))) And IsEmpty(Cells(i, "k")) Then
    Cells(i, "k") = arr(k, 5)
    Cells(i, "p") = arr(k, 6)
endif

这里只判断了"k"是否为空白,如果是,就对k\p两列都进行了更新。原来这么写是因为这两个单元格的判断条件完全相同,写在一起代码避免代码重复。为了更详细的的区分空白单元格,你可以把上面的代码分隔开来,写成:
If (UCase(Cells(i, 5)) = UCase(arr(k, 4))) And IsEmpty(Cells(i, "k")) Then
    Cells(i, "k") = arr(k, 5)
endif
If (UCase(Cells(i, 5)) = UCase(arr(k, 4))) And IsEmpty(Cells(i, "p")) Then
    Cells(i, "p") = arr(k, 6)
endif
分别独立判断就好了。如果有其他类似都这么修改,你自己尝试去改一下。


回复

使用道具 举报

 楼主| 发表于 2019-6-28 14:40 | 显示全部楼层
hfwufanhf2006 发表于 2019-6-28 14:38
"有两列更新第三列不更新"是因为类似下面的条件存在:
If (UCase(Cells(i, 5)) = UCase(arr(k, 4))) An ...

好的,非常感谢
回复

使用道具 举报

 楼主| 发表于 2019-6-28 16:15 | 显示全部楼层
hfwufanhf2006 发表于 2019-6-28 14:38
"有两列更新第三列不更新"是因为类似下面的条件存在:
If (UCase(Cells(i, 5)) = UCase(arr(k, 4))) An ...

老师,按我们这样的条件来处理的话,是不是随着记录多,或是表格里面一些空的信息多,用起来会越来越卡的?我刚刚试了弄5000条的记录,运行就相对慢一点了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-23 16:45 , Processed in 0.325771 second(s), 6 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表