ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 从点数据源找出与已经点距离最近点

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-1-12 11:12 | 显示全部楼层 |阅读模式
本帖最后由 亲亲小布布 于 2024-1-12 15:12 编辑

目的:1.通过AB两列横纵坐标去源数据(H到J列)中找到与之距离最近的点,然后将对应J列的数据写入C列;2.通过DE两列横纵坐标去源数据(H到J列)中找到与之距离最近的点,然后将对应J列的数据写入F列




问题:1.自己在附件中写了代码,但是不知道怎么循环得出那个最小值,只是按照常规的二维数组循环,用的勾股定理求出两点距离,然后用小于50作为判断条件,可能不是精确,并没有找到与之距离最近的那个点。2.按照我的代码,结果输出C、H两列中间会有空单元格,说明程序并没有找到一个匹配条件的点,这个不太可能,因为我的源数据点范围是包含了目的点的,应该总有一个最近的点存在才对。望指教!

说明:1.文件大小超限制,分了三个包!2.源数据有22万行

  1. Sub TEST()
  2.    
  3.     Application.ScreenUpdating = False
  4.     Application.DisplayAlerts = False
  5.     With Sheet1
  6.         .Range("C2:C99999") = ""
  7.         .Range("F2:F99999") = ""
  8.         ar = .Range("a1").CurrentRegion
  9.         br = .Range("H1").CurrentRegion
  10.         'ReDim cr(1 To UBound(ar))
  11.         'ReDim dr(1 To UBound(ar))
  12.         For i = 2 To UBound(ar)
  13.             For x = 2 To UBound(br)
  14.                 If WorksheetFunction.SumSq(Abs(br(x, 1) - ar(i, 1)), Abs(br(x, 2) - ar(i, 2))) <= 50 Then 'sumsq求平方和
  15.                     Cells(i, 3) = Round(br(x, 3), 1)
  16.                 ElseIf WorksheetFunction.SumSq(Abs(br(x, 1) - ar(i, 4)), Abs(br(x, 2) - ar(i, 5))) <= 50 Then
  17.                     Cells(i, 6) = Round(br(x, 3), 1)
  18.                 End If
  19.             Next x
  20.             
  21.         Next i
  22.         '        .Range("g2").Resize(UBound(cr), 1) = cr
  23.         '        .Range("j2").Resize(UBound(dr), 1) = dr
  24.         
  25.     End With
  26.     Application.ScreenUpdating = True
  27.     Application.DisplayAlerts = True
  28. End Sub
复制代码

2024-01-12_103649.jpg

1.part1.rar

2 MB, 下载次数: 29

1.part2.rar

2 MB, 下载次数: 26

1.part3.rar

293.12 KB, 下载次数: 14

TA的精华主题

TA的得分主题

发表于 2024-1-12 13:59 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
你这个代码真是一言难尽...
1、ar只有两列,代码里的ar(i,4)应该会报错
2、计算两列的代码为什么要放到一个if逻辑里?这样子写AB列和DE列只能填入一边
3、cr和dr从头到尾没赋值,又写进表格里干什么?而且很有可能还会错行

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-12 14:20 | 显示全部楼层
dto8323 发表于 2024-1-12 13:59
你这个代码真是一言难尽...
1、ar只有两列,代码里的ar(i,4)应该会报错
2、计算两列的代码为什么要放到一 ...

ar(i,4)是数组里的元素不会报错,放在一个if里是因为总能找到一个最近的点,两列都能写入,cr和dr本来打算用数组方式resiza,结果发现i的值会跳跃,就是说中间的某些行可能在源数据找不到,这应该不可能,但是找不到原因

TA的精华主题

TA的得分主题

发表于 2024-1-12 14:38 | 显示全部楼层
亲亲小布布 发表于 2024-1-12 14:20
ar(i,4)是数组里的元素不会报错,放在一个if里是因为总能找到一个最近的点,两列都能写入,cr和dr本来打 ...

ar数组只有2列,你ar(i,4)会不报错?

TA的精华主题

TA的得分主题

发表于 2024-1-12 14:57 | 显示全部楼层
不会报错的吧,ar = .Range("a1").CurrentRegion是到F列的,因为第一行有标题。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-13 10:46 | 显示全部楼层
亲亲小布布 发表于 2024-1-12 14:20
ar(i,4)是数组里的元素不会报错,放在一个if里是因为总能找到一个最近的点,两列都能写入,cr和dr本来打 ...

ar确实不会报错,是从第一行开始读的,这里是我看漏了。
但你那个x的循环并没有筛选最小值的功能:
1.假如已经写入一个距离为0的点的Z值,之后也会被另一个距离小于50的点的Z值覆盖掉;
2.如果所有距DE列的点距离小于50的源数据点与AB列的点距离也小于50,那么这个if循环根本就不会跳转到DE列的代码,而是会全部写到AB列就结束,也就是说DE列会出现空值;
3.按你的代码,如果确实在源数据中存在目标点,至少C列应该不会是空的,建议将50的限制改大一点再看看,例如10000。如果改大之后C列就齐活了,那就说明源数据中的确是不存在距离50以下的点。

另外,22万行直接用遍历来写速度会可以预见的慢,优化一下距离算法至少可以提升30倍以上的速度,这个是有实例的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-15 09:02 | 显示全部楼层
dto8323 发表于 2024-1-13 10:46
ar确实不会报错,是从第一行开始读的,这里是我看漏了。
但你那个x的循环并没有筛选最小值的功能:
1. ...

感谢指教,我找找相关算法优化

TA的精华主题

TA的得分主题

发表于 2024-1-15 09:13 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-1-15 15:30 | 显示全部楼层
本帖最后由 yynrzwh 于 2024-1-15 16:33 编辑
  1. Sub test()

  2. lr = Cells(Rows.Count, 1).End(3).Row
  3. Range("c2:c" & lr) = ""
  4. Range("f2:f" & lr) = ""
  5. ar = Range("a1").CurrentRegion
  6. br = Range("h1").CurrentRegion
  7.     For i = 2 To UBound(ar)
  8.         For j = 1 To 6 Step 3
  9.             tem = 10 ^ 10: r = 0
  10.             For x = 2 To UBound(br)
  11.                 s1 = Abs(br(x, 1) - ar(i, j)) 'X差值
  12.                 s2 = Abs(br(x, 2) - ar(i, j + 1)) 'Y差值
  13.                 s = VBA.Sqr(s1 ^ 2 + s2 ^ 2) '差值平方和的平方根
  14.                 If s < tem Then tem = s: r = x '获得最小值
  15.             Next x
  16.             If r > 0 Then ar(i, j + 2) = br(r, 3)
  17.         Next j
  18.     Next i
  19. Range("a1").CurrentRegion = ar
  20. End Sub
复制代码

计算距离的公式我不懂,这是根据你的意思写的。
平方和是一个很大的数字,开始几个都是10 的9次方以上。
按勾股定理的话,是不是应该取平方根?
不过并不影响取最小值。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-6-29 12:10 , Processed in 0.047473 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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