ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 可能发错版块了,请管理帮忙删除!!!

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-8-19 21:26 | 显示全部楼层 |阅读模式
本帖最后由 supper_idol 于 2024-8-20 18:52 编辑

主要想要这个VBA宏代码实现:从一个名为"所有人员名单"的源工作表中提取不重复的姓名,并将它们填充到另一个名为"Sheet1"的目标工作表中,它通过排除已存在的姓名,将新的不重复的姓名填充到目标工作表中,以避免重复和遗漏。并用F2的值在excel簿中另存这张表。

以下是部分需求:
设置源和目标工作表:将"所有人员名单"设置为源工作表,"Sheet1"设置为目标工作表。
定义源数据和排除数据的范围:源数据范围是源工作表的A1到A58单元格,排除数据范围是目标工作表的C24到C40单元格。
提取排除姓名:排除范围中的每个单元格,按"、"分隔符分割姓名,并将它们添加到排除字典中。(同名的问题没想到怎么解决)
消息框提示:显示一个消息框,告知用户填充完成,并显示填充了多少个姓名。并另存为新表完毕(未完成)

以下VBA函数是我结合Kimi折腾出来的,虽然能完成数据的填充,但是运行会提示下标越界
  1. Sub FillSheet1ColumnByColumnWithExclusionCriteria()
  2.     ' 声明变量
  3.     Dim sourceWs As Worksheet
  4.     Dim destWs As Worksheet
  5.     Dim sourceRange As Range
  6.     Dim exclusionRange As Range
  7.     Dim cell As Range
  8.     Dim exclusionCell As Range
  9.     Dim dictNames As Object
  10.     Dim dictExclusions As Object
  11.     Dim namesArray() As Variant
  12.     Dim currentNameIndex As Long
  13.     Dim col As Integer
  14.     Dim row As Long

  15.     ' 设置源工作表和目标工作表
  16.     Set sourceWs = ThisWorkbook.Sheets("所有人员名单") ' 源数据工作表
  17.     Set destWs = ThisWorkbook.Sheets("Sheet1") ' 目标工作表

  18.     ' 创建字典对象来存储不重复的姓名和排除的姓名列表
  19.     Set dictNames = CreateObject("Scripting.Dictionary")
  20.     Set dictExclusions = CreateObject("Scripting.Dictionary")

  21.     ' 定义源数据的范围和排除数据的范围
  22.     Set sourceRange = sourceWs.Range("A1:A58")
  23.     Set exclusionRange = destWs.Range("C24:C40")

  24.     ' 从排除范围中提取姓名并存储在字典中
  25.     For Each exclusionCell In exclusionRange
  26.         If Not IsEmpty(exclusionCell.Value) Then
  27.             Dim exclusionNames As Variant
  28.             exclusionNames = Split(exclusionCell.Value, "、") ' 确保使用正确的分隔符
  29.             Dim name As Variant
  30.             For Each name In exclusionNames
  31.                 If Trim(name) <> "" Then
  32.                     dictExclusions.Add Trim(name), True ' 使用Add而不是Exists
  33.                 End If
  34.             Next name
  35.         End If
  36.     Next exclusionCell

  37.     ' 从源数据中提取不重复的姓名
  38.     For Each cell In sourceRange
  39.         If cell.Value <> "" Then
  40.             dictNames(cell.Value) = True
  41.         End If
  42.     Next cell

  43.     ' 将不重复的姓名列表转换为数组
  44.     namesArray = dictNames.Keys()

  45.     ' 初始化当前姓名索引
  46.     currentNameIndex = LBound(namesArray)

  47.     ' 按列遍历目标范围 "A4:F23"
  48.     For col = 1 To destWs.Range("A4:F23").Columns.Count
  49.         ' 遍历目标列的每一行
  50.         For row = 4 To 23
  51.             With destWs.Cells(row, col)
  52.                 If IsEmpty(.Value) Then
  53.                     ' 找到不在排除列表中的姓名并填充
  54.                     While currentNameIndex <= UBound(namesArray) And _
  55.                         dictExclusions.Exists(namesArray(currentNameIndex))
  56.                         currentNameIndex = currentNameIndex + 1
  57.                     Wend
  58.                     If currentNameIndex <= UBound(namesArray) Then
  59.                         .Value = namesArray(currentNameIndex)
  60.                         currentNameIndex = currentNameIndex + 1 ' 准备填充下一个空单元格
  61.                     End If
  62.                 End If
  63.             End With
  64.         Next row
  65.     Next col

  66.     ' 清理
  67.     Set sourceWs = Nothing
  68.     Set destWs = Nothing
  69.     Set sourceRange = Nothing
  70.     Set exclusionRange = Nothing
  71.     Set dictNames = Nothing
  72.     Set dictExclusions = Nothing

  73.     MsgBox "填充完成,共填充了 " & (currentNameIndex - LBound(namesArray)) & " 个姓名。"
  74.     ' 检查F2单元格是否包含文本
  75.     If Not IsEmpty(destWs.Range("F2").Value) Then
  76.         ' 定义新工作表的名称
  77.         Dim newSheetName As String
  78.         newSheetName = destWs.Range("F2").Value
  79.         
  80.         ' 创建一个新的工作表并命名
  81.         Dim newWs As Worksheet
  82.         Set newWs = ThisWorkbook.Worksheets.Add
  83.         newWs.Name = newSheetName
  84.         
  85.         ' 复制源工作表的内容到新工作表
  86.         destWs.Cells.Copy newWs.Cells
  87.         
  88.         ' 可选:删除源工作表
  89.         ' destWs.Delete
  90.         
  91.         ' 显示消息框,告知用户新工作表已创建
  92.         MsgBox "新工作表 '" & newSheetName & "' 已创建。"
  93.     Else
  94.         MsgBox "F2 单元格为空,无法创建新工作表。"
  95.     End If
  96. End Sub
复制代码
求大佬帮忙!!!!
点名册.rar (18.12 KB, 下载次数: 8)

TA的精华主题

TA的得分主题

发表于 2024-8-20 18:43 | 显示全部楼层
这段试试符不符合你的需求,注意"Sheet1"表F2单元格需要用文本格式,不然直接取到日期格式的"/"符号来命名文件会报错。

  1. Sub FillSheet1ColumnByColumnWithExclusionCriteria()
  2.     ' 声明变量
  3.     Dim sourceWs As Worksheet
  4.     Dim destWs As Worksheet
  5.     Dim sourceRange As Range
  6.     Dim exclusionRange As Range
  7.     Dim cell As Range
  8.     Dim exclusionCell As Range
  9.     Dim dictNames As Object
  10.     Dim dictExclusions As Object
  11.     Dim namesArray() As Variant
  12.     Dim currentNameIndex As Long
  13.     Dim col As Integer
  14.     Dim row As Long
  15.     Dim filledCount As Long

  16.     ' 设置源工作表和目标工作表
  17.     Set sourceWs = ThisWorkbook.Sheets("所有人员名单") ' 源数据工作表
  18.     Set destWs = ThisWorkbook.Sheets("Sheet1") ' 目标工作表

  19.     ' 创建字典对象来存储不重复的姓名和排除的姓名列表
  20.     Set dictNames = CreateObject("Scripting.Dictionary")
  21.     Set dictExclusions = CreateObject("Scripting.Dictionary")

  22.     ' 定义源数据的范围和排除数据的范围
  23.     Set sourceRange = sourceWs.Range("A1:A58")
  24.     Set exclusionRange = destWs.Range("C24:C40")

  25.     ' 从排除范围中提取姓名并存储在字典中
  26.     For Each exclusionCell In exclusionRange
  27.         If Not IsEmpty(exclusionCell.Value) Then
  28.             Dim exclusionNames As Variant
  29.             exclusionNames = Split(exclusionCell.Value, "、") ' 确保使用正确的分隔符
  30.             Dim name As Variant
  31.             For Each name In exclusionNames
  32.                 name = Trim(name)
  33.                 If name <> "" And Not dictExclusions.Exists(name) Then
  34.                     dictExclusions.Add name, True
  35.                 End If
  36.             Next name
  37.         End If
  38.     Next exclusionCell

  39.     ' 从源数据中提取不重复的姓名
  40.     For Each cell In sourceRange
  41.         If cell.Value <> "" And Not dictExclusions.Exists(cell.Value) And Not dictNames.Exists(cell.Value) Then
  42.             dictNames.Add cell.Value, True
  43.         End If
  44.     Next cell

  45.     ' 将不重复的姓名列表转换为数组
  46.     namesArray = dictNames.Keys()

  47.     ' 初始化当前姓名索引
  48.     currentNameIndex = LBound(namesArray)
  49.     filledCount = 0

  50.     ' 按列遍历目标范围 "A4:F23"
  51.     For col = 1 To destWs.Range("A4:F23").Columns.Count
  52.         ' 遍历目标列的每一行
  53.         For row = 4 To 23
  54.             With destWs.Cells(row, col)
  55.                 If IsEmpty(.Value) Then
  56.                     ' 找到不在排除列表中的姓名并填充
  57.                     If currentNameIndex <= UBound(namesArray) Then
  58.                         .Value = namesArray(currentNameIndex)
  59.                         currentNameIndex = currentNameIndex + 1 ' 准备填充下一个空单元格
  60.                         filledCount = filledCount + 1
  61.                     End If
  62.                 End If
  63.             End With
  64.         Next row
  65.     Next col

  66.     ' 提示填充结果
  67.     MsgBox "填充完成,共填充了 " & filledCount & " 个姓名。"

  68.     ' 检查F2单元格是否包含文本
  69.     If Not IsEmpty(destWs.Range("F2").Value) Then
  70.         ' 定义新工作表的名称
  71.         Dim newSheetName As String
  72.         newSheetName = destWs.Range("F2").Value
  73.         
  74.         ' 验证新工作表名称是否有效
  75.         newSheetName = Application.WorksheetFunction.Clean(newSheetName)
  76.         newSheetName = Left(newSheetName, 31) ' 限制名称长度为31个字符

  77.         ' 如果名称为空或包含无效字符,则给出错误提示
  78.         If newSheetName = "" Then
  79.             MsgBox "F2 单元格的名称无效,请确保名称不为空且不包含无效字符。"
  80.             Exit Sub
  81.         End If
  82.         
  83.         ' 保存当前工作表为新的文件
  84.         Dim newWorkbook As Workbook
  85.         Set newWorkbook = Workbooks.Add
  86.         destWs.Copy Before:=newWorkbook.Sheets(1)
  87.         newWorkbook.Sheets(1).Name = newSheetName
  88.         
  89.         ' 保存新工作簿
  90.         Dim filePath As String
  91.         filePath = ThisWorkbook.Path & "" & newSheetName & ".xlsx"
  92.         newWorkbook.SaveAs filePath
  93.         newWorkbook.Close
  94.         
  95.         ' 显示消息框,告知用户新工作簿已保存
  96.         MsgBox "新工作簿 '" & newSheetName & "' 已保存到:" & filePath
  97.     Else
  98.         MsgBox "F2 单元格为空,未保存新工作簿。"
  99.     End If

  100.     ' 清理
  101.     Set sourceWs = Nothing
  102.     Set destWs = Nothing
  103.     Set sourceRange = Nothing
  104.     Set exclusionRange = Nothing
  105.     Set dictNames = Nothing
  106.     Set dictExclusions = Nothing
  107. End Sub
复制代码


评分

1

查看全部评分

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

本版积分规则

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

GMT+8, 2024-12-4 16:20 , Processed in 0.041490 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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