ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3783|回复: 26

[已解决] 谢谢各位老师的解答。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-7-25 08:37 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 excelcpeh 于 2018-7-27 21:59 编辑

比较难的提取。能否一步快速得到结果。

极速提取.zip

207.23 KB, 下载次数: 44

TA的精华主题

TA的得分主题

发表于 2018-7-25 09:07 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
'估计差不多,自己测试一下

Option Explicit

Sub test()
  Dim arr, brr, crr, dic, drr, temp, t As String
  Dim i As Long, j As Long, n As Long
  Set dic = CreateObject("scripting.dictionary")
  With Sheets("sheet1")
    arr = .Range("d1:d" & .Cells(Rows.Count, "d").End(xlUp).Row)
    brr = .[g1].CurrentRegion
  End With
  ReDim crr(1 To UBound(brr, 1), 1 To UBound(brr, 2))
  For i = 1 To UBound(arr, 1)
    If Len(arr(i, 1)) > 0 Then
      dic.RemoveAll
      For j = 1 To UBound(brr, 1)
        t = brr(j, arr(i, 1)): If Len(t) = 0 Then Exit For
        dic(t) = vbNullString
      Next
      drr = dic.keys: temp = drr
      Call msort(drr, CLng(LBound(drr)), CLng(UBound(drr)), temp)
      n = n + 1
      For j = 0 To UBound(drr): crr(j + 1, n) = drr(j): Next
    End If
  Next
  With Sheets("结果")
    .Cells.ClearContents
    .[b1].Resize(UBound(crr, 1), UBound(crr, 2)) = crr
  End With
End Sub

Function msort(arr, first, last, temp)
  Dim i As Long, j As Long, k  As Long, mid  As Long
  If first <> last Then
    mid = Int((first + last) / 2)
    msort arr, first, mid, temp
    msort arr, mid + 1, last, temp
    i = first: j = mid + 1: k = first
    While i <= mid And j <= last
      If arr(i) <= arr(j) Then
        temp(k) = arr(i): k = k + 1: i = i + 1
      Else
        temp(k) = arr(j): k = k + 1: j = j + 1
      End If
    Wend
    While i <= mid
      temp(k) = arr(i): k = k + 1: i = i + 1
    Wend
    While j <= last
      temp(k) = arr(j): k = k + 1: j = j + 1
    Wend
    For i = first To last: arr(i) = temp(i): Next
  End If
End Function

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-25 11:11 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 excelcpeh 于 2018-7-25 11:16 编辑
一把小刀闯天下 发表于 2018-7-25 09:07
'估计差不多,自己测试一下

Option Explicit

谢谢小刀老师的回复~
结果不对哦。
1.当D列输入1个数字时,代码不能运行。
2.给定的示例数据有81列,每列向右60列为一组。则要有组成81-60=21组数据。
3.比如当输入一个数字31时。第一组60列:31组含有的数据见下面附件。

极速提取2.zip

220.31 KB, 下载次数: 7

TA的精华主题

TA的得分主题

发表于 2018-7-25 12:20 | 显示全部楼层
excelcpeh 发表于 2018-7-25 11:11
谢谢小刀老师的回复~
结果不对哦。
1.当D列输入1个数字时,代码不能运行。

没看不懂:

“假如只求第一组60列。在D列输入31.则提取第一组中31列含有的数据总共有98个”

98个数怎么来的?没看到有条件约束。如果57列中都出现过的数字那没找到符合条件的 (31-6+59=84,总的数据列为81,也就是当前只能取57列)

觉得看懂一个题目很多时候比写代码费劲的多

TA的精华主题

TA的得分主题

发表于 2018-7-25 12:22 | 显示全部楼层
excelcpeh 发表于 2018-7-25 11:11
谢谢小刀老师的回复~
结果不对哦。
1.当D列输入1个数字时,代码不能运行。

连描述都说得不清楚,只有自己懂是什么意思,别人做,当然都是错的啦

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-25 12:40 来自手机 | 显示全部楼层
本帖最后由 excelcpeh 于 2018-7-25 12:43 编辑
一把小刀闯天下 发表于 2018-7-25 12:20
没看不懂:

“假如只求第一组60列。在D列输入31.则提取第一组中31列含有的数据总共有98个”

抱歉老师。
因给定各列数据本身不含重复。所以98个数据来源可以这样理解:即60列里出现31次的数据集合。比如028它在31列含有,也即出现31次。

TA的精华主题

TA的得分主题

发表于 2018-7-25 13:51 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
excelcpeh 发表于 2018-7-25 12:40
抱歉老师。
因给定各列数据本身不含重复。所以98个数据来源可以这样理解:即60列里出现31次的数据集合。 ...

你知道自己还是说的自己才明白是什么意思吗?你举的例子,根本就没人明白你说的那些数值来源何处,如何比对

TA的精华主题

TA的得分主题

发表于 2018-7-25 15:56 | 显示全部楼层
本帖最后由 一把小刀闯天下 于 2018-7-25 16:05 编辑
excelcpeh 发表于 2018-7-25 12:40
抱歉老师。
因给定各列数据本身不含重复。所以98个数据来源可以这样理解:即60列里出现31次的数据集合。 ...

‘进入猜题模式,好像差不多。三楼附件

Option Explicit

Sub test()
  Dim arr, brr, crr, dic, drr, temp, t As String, key, offset
  Dim i As Long, j As Long, k As Long, kk As Long, m As Long
  Set dic = CreateObject("scripting.dictionary")
  Application.ScreenUpdating = False
  With Sheets("sheet1")
    arr = .Range("d1:d" & .Cells(Rows.Count, "d").End(xlUp).Row + 1)
    brr = .[g1].CurrentRegion
  End With
  ReDim crr(1 To UBound(brr, 1), 1 To UBound(brr, 2) - 60) As String
  ReDim drr(1 To UBound(brr, 1)) As String: temp = drr
  Sheets("结果").Cells.ClearContents
  For i = 1 To UBound(arr, 1) - 1
    If Len(arr(i, 1)) > 0 Then
      For j = 1 To UBound(brr, 2) - 60
        dic.RemoveAll: m = 0
        For k = j To j + 59
          For kk = 1 To UBound(brr, 1)
            If Len(brr(kk, k)) = 0 Then Exit For
            dic(brr(kk, k)) = dic(brr(kk, k)) + 1
        Next kk, k
        For Each key In dic.keys
          If dic(key) = arr(i, 1) Then
            m = m + 1: drr(m) = key
          End If
        Next
        If m > 0 Then
          Call msort(drr, CLng(1), CLng(m), temp)
          For k = 1 To m: crr(k, j) = drr(k): Next
        End If
      Next
    End If
    Sheets("结果").[b1].offset(, offset).Resize(UBound(crr, 1), UBound(crr, 2)) = crr
    offset = offset + UBound(crr, 2) + 1
  Next
  Application.ScreenUpdating = True
End Sub

Function msort(arr, first, last, temp)
  Dim i As Long, j As Long, k  As Long, mid  As Long
  If first <> last Then
    mid = Int((first + last) / 2)
    msort arr, first, mid, temp
    msort arr, mid + 1, last, temp
    i = first: j = mid + 1: k = first
    While i <= mid And j <= last
      If arr(i) <= arr(j) Then
        temp(k) = arr(i): k = k + 1: i = i + 1
      Else
        temp(k) = arr(j): k = k + 1: j = j + 1
      End If
    Wend
    While i <= mid
      temp(k) = arr(i): k = k + 1: i = i + 1
    Wend
    While j <= last
      temp(k) = arr(j): k = k + 1: j = j + 1
    Wend
    For i = first To last: arr(i) = temp(i): Next
  End If
End Function

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-25 18:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
一把小刀闯天下 发表于 2018-7-25 15:56
‘进入猜题模式,好像差不多。三楼附件

Option Explicit

非常感谢老师的回复。 81列数据,每组向右取60列一组。共21组组数据。所得结果只有21列的。
1.当D列只输入1个数字时,得到正确答案。
2.当D列输入2个数字或更多时,即每组,同时把输入数字出现的个数提取。结果是合并在一列的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-25 18:48 | 显示全部楼层
一把小刀闯天下 发表于 2018-7-25 15:56
‘进入猜题模式,好像差不多。三楼附件

Option Explicit

按输入1个数字得到正确答案,那么:
第1次输入31,得到正确答案。
第2次输入21,得到正确答案。
第3次输入22,得到正确答案。
第4次输入42,得到正确答案。
第5次输入18,得到正确答案。

如果一次同时输入 :31,21,22,42,18,那么结果就是把每个答案的B-V列对应相加。总数还是21列的。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-1-11 03:52 , Processed in 0.027246 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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