ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 请教关于通过VBA实现单元格 十字定位

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-5-4 18:37 | 显示全部楼层 |阅读模式
请教前辈:       有很多工作薄,每个工作薄有很多工作表,里面数据也有千来条,数据很多,
       想要实现十字定位功能,希望通过VBA来实现,查了很多帖子,没找到适合的,求前辈指教;有以下几项条件:

1、不改变原来单元格背景颜色
2、该VBA适用于本机所有工作薄
3、如果在工具栏能有个开关按钮,那就更好了。
    望前辈不吝赐教,谢谢!

十字光标不改变单元格背景色

十字光标不改变单元格背景色

光标可适用于本机所有工作薄,并且带开关选项

光标可适用于本机所有工作薄,并且带开关选项
头像被屏蔽

TA的精华主题

TA的得分主题

发表于 2018-5-4 18:57 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-5-4 19:12 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
朱荣兴 发表于 2018-5-4 18:57
关键的没说,定位条件??规则????

谢谢前辈回答
鼠标点击任意单元格(包括空白单元格),该单元格所在 行和列 均用颜色突出显示,只显示,不改变高亮区域 单元格的原有背景色

TA的精华主题

TA的得分主题

发表于 2018-5-4 19:17 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-5-4 19:22 | 显示全部楼层
楼主是不是需要 行列高亮显示得效果?如下图。

论坛可以搜索,有很多啊。
aa.gif

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-5-4 19:25 | 显示全部楼层
不知道为什么 发表于 2018-5-4 19:22
楼主是不是需要 行列高亮显示得效果?如下图。

论坛可以搜索,有很多啊。

是这种效果,但是论坛中的会删除原有单元格的背景颜色,

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-5-4 19:28 | 显示全部楼层
ww87725244 发表于 2018-5-4 19:17
相当于做一个插件

对哦,我找找看有没有相应的插件,这项功能估计会非常实用

TA的精华主题

TA的得分主题

发表于 2018-5-5 11:58 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
hiiy54 发表于 2018-5-4 19:28
对哦,我找找看有没有相应的插件,这项功能估计会非常实用
  1. ribbon功能区

  2. <!--功能区壳 2006/01 是2007 2009/07 只是2010-->
  3. <customUI onLoad="RibbonUI_OnLoad" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  4. <!--功能区-->
  5. <ribbon startFromScratch="false">
  6. <!--选项卡-->
  7.   <tabs>
  8. <!--创建选项卡-->
  9.    <tab id="创建选项卡" label="鼠标移动着色" insertAfterMso="TabHome">
  10.   <!--创建"移动鼠标着色"组-->
  11.    <group id="鼠标移动着色" label="鼠标移动着色">
  12.     <button id="A" label="行着色" screentip="突出显示行" supertip="对鼠标指针所指向的行进行着色,方便查看工作表数据。" onAction="Mouse" size="large" imageMso="ViewBackToColorView" />
  13.     <button id="B" label="列着色" screentip="突出显示列" supertip="对刀柄指针所指向的列进行着色,方便查看工作表数据。" onAction="Mouse" size="large" imageMso="ChartInsert" />
  14.     <button id="C" label="行与列皆着色" screentip="突出显示行与列" supertip="对刀柄指针所指向的行与列进行同时着色,方便查看工作表数据。" onAction="Mouse" size="large" imageMso="ViewDisplayInHighContrast" />
  15.     <toggleButton id="D" label="停止着色" screentip="停止着色" supertip="暂时停止着色,再次单击时可以重新开始着色。" onAction="CloseCol" size="large" imageMso="Lock" />
  16.    </group>
  17.   <!--创建"移动鼠标着色"组结束-->
  18.    </tab>
  19.    <!--创建选项卡结束-->
  20.   </tabs>
  21.   <!--选项卡-->
  22. </ribbon>
  23. <!--功能区结束-->
  24. </customUI>
  25. <!--功能区壳-->
  26. </ribbon>
  27. </customUI>
复制代码


鼠标移动而着色.gif

鼠标移动而着色_Ribbon_简体.zip

247.57 KB, 下载次数: 138

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-5-5 12:30 | 显示全部楼层
hiiy54 发表于 2018-5-4 19:28
对哦,我找找看有没有相应的插件,这项功能估计会非常实用
  1. 模块:Ribbon_载入
  2. Public rib As IRibbonUI '声明一个公共变量,IRibbonUI代表一个Ribbon类的对象实例
  3. Sub RibbonUI_OnLoad(ribbon As IRibbonUI) '此过程将在启动工作簿时执行,作用是将工能区对象Ribbon赋予变量rib,即载入缓存中,供其它代码随时调用
  4. '将IRibbonUI类赋予变量rib,从而载入缓存供以后调用
  5. Set rib = ribbon
  6. 'rib.ActivateTab "鼠标移动而着色"       '方法1:打开文件时激活指定的选项卡
  7. Application.SendKeys "%Y{RETURN}"   '方法2:打开文件时激活指定的选项卡
  8. Application.SendKeys "{NUMLOCK}"
  9. End Sub


  10. 模块:鼠标移动而着色

  11. 'VBA中主要需着色和关闭着色两个过程,为了方便,以及避免破坏Execl自带的复制与剪切功能,需要更多Sub和Function过程
  12. '声明关于鼠标坐标相关的变量

  13. '复制对象"的自定义函数
  14. '以下代码主要用于从剪贴板中获取复制或剪切的单元格地址,使用了较多的API函数
  15. '由于剪贴板取出的地址是R1C1样式,所以利用自定义函数RCTransition将它转换成A1样式,否则会出错
  16. Private Declare Function GlobalLock Lib "kernel32" (ByVal ClipContent As Long) As Long
  17. Private Declare Function GlobalUnlock Lib "kernel32" (ByVal ClipContent As Long) As Long
  18. Private Declare Function GlobalSize Lib "kernel32" (ByVal ClipContent As Long) As Long
  19. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  20. Private Declare Function CloseClipboard Lib "user32" () As Long
  21. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  22. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  23. '声明关于鼠标坐目标相关变量
  24. Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
  25. Type POINTAPI
  26.     x As Long
  27.     Y As Long
  28. End Type

  29. Dim 坐标 As POINTAPI
  30. '声明颜色选择器的相关变量
  31. Private Type ChooseColor
  32. lStructSize As Long
  33. hwndOwner As Long
  34. hInstance As Long
  35. rgbResult As Long
  36. lpCustColors As String
  37. Flags As Long
  38. lCustData As Long
  39. lpfnHook As Long
  40. lpTemplateName As String
  41. End Type

  42. ''API函数ChooseColor调用Windows系统的颜色对话框
  43. Private Declare Function ChooseColorAPI Lib "comdlg32.dll" Alias "ChooseColorA" (pChoosecolor As ChooseColor) As Long
  44. Dim CustomColors() As Byte
  45. '声明其它变量
  46. Dim 原单元格 As Range, 关闭 As Boolean, 当前单元格 As Range, 着色方式 As String

  47. '主体程序:对鼠标移过的行或列进行着色
  48. Sub MouseColor(Str As String)
  49. '获取颜色
  50.     Dim ChColor As ChooseColor, CustColor(16) As Long, ReturnCol As Long, rng As Range, CutOrCopy As Integer
  51.     ChColor.lStructSize = Len(ChColor)
  52.     ChColor.hInstance = 1
  53.     ChColor.lpCustColors = StrConv(CustomColors, vbUnicode)
  54.     ChColor.Flags = 0
  55.     ReturnCol = ChooseColorAPI(ChColor)
  56.     If ReturnCol <> 0 Then col = ChColor.rgbResult Else Exit Sub
  57.     关闭 = False  '将False赋值给变量"关闭"
  58.     Do   '循环执行过程
  59.         If 关闭 = True Then Exit Do  '如果变量"关闭"为True就停止循环
  60.         GetCursorPos 坐标     '获取鼠目标坐标体
  61.         On Error Resume Next   '遇到错误时继续执行下面的语句
  62.         Set 当前单元格 = ActiveWindow.RangeFromPoint(坐标.x, 坐标.Y)  '根据鼠目标坐标得到鼠标指针下的单元格的地址
  63.         If 当前单元格 Is Nothing Then  '如果鼠标指针下不是单元格
  64.             [ColorCells].FormatConditions.Delete  '删除名称为ColorCells的区域的条件格式
  65.             ActiveWorkbook.Names("ColorCells").Delete     '删除名称ColorCells
  66.         Else
  67.             If 当前单元格.Address <> 原单元格.Address Then  '如果当前鼠标指针下的单元格与记录的上一个地址不等时
  68.                 [ColorCells].FormatConditions.Delete  '删除条件格式
  69.             If Str = "A" Then '如果菜单按钮是第一个(行着色)
  70.             '将当前行中可见区域命名为"ColorCells"。需要注意一点:Range 部分是为了得到可见区域,而不需要把整行都添加颜色,那样会浪费内存
  71.                 Intersect(当前单元格.EntireRow, Range(当前单元格.EntireRow.Cells(1), ActiveWindow.VisibleRange)).name = "ColorCells"
  72.             ElseIf Str = "B" Then       '如果菜单按钮是第一个(列着色)
  73.                 Intersect(当前单元格.EntireColumn, Range(当前单元格.EntireColumn.Cells(1), ActiveWindow.VisibleRange)).name = "ColorCells"
  74.             Else  '否则将当前行或当前列的可见区域命名为"ColorCells"
  75.                 Intersect(Union(当前单元格.EntireColumn, 当前单元格.EntireRow), Range([A1], ActiveWindow.VisibleRange)).name = "ColorCells"
  76.              End If
  77.              '如果剪切模式为True,那么调用过程"复制对象",且将复制的对象赋值给变量rng
  78.              If Application.CutCopyMode Then Set rng = 复制对象 Else Set rng = Nothing
  79.              CutOrCopy = Application.CutCopyMode    '记录当前的剪切模式
  80.              With [ColorCells].FormatConditions   '引用名称"ColorCells"所代表的区域的条件格式
  81.                 .Delete       '删除条件格式
  82.                 .Add xlExpression, , "TRUE"    '添加条件格式
  83.                 .Item(1).Interior.Color = col   '设置条件格式的颜色
  84.             End With
  85.             If CutOrCopy = xlCopy Then rng.Copy  'If当前的剪切模式为复制状态,则复制rng区域
  86.             If CutOrCopy = xlCut Then rng.Cut         'If当前的剪切模式为剪切状态,则剪切rng区域
  87.         End If
  88.         Set 原单元格 = 当前单元格 '将变量"当前单元格"赋值给变量"原单元格"
  89.     End If
  90.     DoEvents   '转交控制权,此处的目的是释放内存,否则一旦执行后,就再也不能执行其它任何工作了
  91.   Loop
  92. End Sub

  93. Public Function 复制对象() As Range   '---"复制对象"的自定义函数
  94.     Dim Myarr() As Byte, ClipContent, nClipsize, lpData As Long, sSource, sTemp() As String
  95.     Dim 工作簿, 工作表, 单元格 As String
  96.     On Error GoTo Err    '遇到错误时,跳转到Err:标签处
  97.     OpenClipboard 0&  '打开剪贴板
  98.     ClipContent = GetClipboardData(49154)   '获取剪贴板的数据,49154在此处代表剪贴板中有Range对象
  99.     If CBool(ClipContent) Then   '如果有数据
  100.     '获取数据
  101.         nClipsize = GlobalSize(ClipContent)
  102.         lpData = GlobalLock(ClipContent)   '锁定内存中指定的内存块,并返回一个地址值
  103.         If lpData <> 0 Then
  104.             ReDim Myarr(0 To nClipsize - 1) As Byte
  105.             CopyMemory Myarr(0), ByVal lpData, nClipsize  '将数据复制到数组变量中
  106.             sSource = StrConv(Myarr, vbUnicode)  '得到一个包括工作簿路径的单元格对象地址(R1C1格式)
  107.             sTemp = Split(sSource, Chr(0))  '从sSource中获取工作簿、工作表、单元格地址部分字符串,删除其它字符
  108.             '获取工作薄名称
  109.             If InStr(sTemp(1), "") Then 工作簿 = Mid(sTemp(1), InStrRev(sTemp(1), "") + 1) Else 工作薄 = sTemp(1)
  110.             '获取工作表名称
  111.             工作表 = Left(sTemp(2), InStr(sTemp(2), "!") - 1)
  112.             '获取单元格地址
  113.             单元格 = RCTransition(Mid(sTemp(2), InStr(sTemp(2), "!") + 1))
  114.             Set 复制对象 = Workbooks(工作簿).Sheets(工作表).Range(单元格)  '引用转换后的详细地址(该地址由剪贴板获取)
  115.         End If
  116.             GlobalUnlock ClipContent    '解除锁定的内存块
  117.     Else
  118.         Set 复制对象 = Nothing
  119.     End If
  120.     CloseClipboard    '关闭剪贴板
  121. Err:
  122. End Function

  123. '将A1C1形式的引用转换成A1形式的引用,例如:将"R2C1"转换成"$A$2";"R2C2:R10C3"转换成"$B$2:$C$10"
  124. Function RCTransition(ByVal rangeAdd As String) As String   'A1C1的引用转换成A1引用
  125.     If InStr(rangeAdd, ":") Then '如果地址中有":"字符时
  126.     '则将冒号":"前后的字符串分两次转换再串联起来
  127.         RCTransition = RCTransition(Split(rangeAdd, ":")(0)) & ":" & RCTransition(Split(rangeAdd, ":")(1))
  128.     Else    '否则将R1C1模式的单元格地址转换成A1引用样式
  129.         RCTransition = Application.ConvertFormula(rangeAdd, xlR1C1, xlA1)
  130.     End If
  131. End Function

  132. Sub Mouse(control As IRibbonControl)  '与三个菜单相关联的Sub过程
  133. 着色方式 = control.Id  '获取当前单击的按钮的ID
  134. Call MouseColor(着色方式)  '调用同一个过程,但是由于ID不同,所以会执行不同的代码
  135. End Sub

  136. Sub CloseCol(control As IRibbonControl, pressed As Boolean)  '单击第四个菜单时执行的过程,用于关闭或重启着色
  137. '如果按钮呈按下状态,则将变量赋值为True,否则再次调用过程MouseColor
  138.     On Error Resume Next   '遇到错误时继续执行下面的语句
  139.     If pressed Then 关闭 = True Else If Len(着色方式) > 0 Then Call MouseColor(着色方式)
  140.     [ColorCells].FormatConditions.Delete  '删除名称为ColorCells的区域的条件格式
  141.     ActiveWorkbook.Names("ColorCells").Delete     '删除名称ColorCells
  142. End Sub

  143. '以上代码有五个重点:
  144. '1、获取鼠标指针的坐标
  145.     '由于需要鼠标指针移到哪里,哪一行或哪一列就要突出显示,所以需要用代码获取鼠目标屏幕位置.VBA自身没有任何方法获取此坐标值,
  146. '所以调用API中的GetCursorPos函数来取得鼠标指针的X和Y的坐标值,然后配合RangeFromPoint方法取得该坐标下的单元格地址。

  147. '2、创建颜色对话框
  148.      '用VBA开发一个颜色对话框比较复杂,所以本例通过API函数ChooseColor调用Windows系统的颜色对话框,
  149. '提供给用户自定义颜色的选项,会更具人性化。

  150. '3、条件格式
  151.     '突出显示一个区域,最方便的是采用颜色格式,根据按钮的ID决定对行还是对列突出显示,或是行列同时突出显示,
  152. '为了方便,将需要突出显示的区域命名为一个名称"ColorCells",后续只需要通过[ColorCells]调用该区域即可,
  153. '由于鼠标不停移动,所以南要随时更新亲名称和条件格式,采用Do   Loop循环语句反复运行,直到条件"关闭"值为True时才停止。
  154. '在对任意单元格添加条件格式前,需要删除上一次的条件格式。

  155. '4、区域范围
  156.     '由于条件格式的范围越大,占用内存越多,所以采用ActiveWindow.VisibleRange属性限制只对当前窗口中的可见区域生效,在屏幕以外的区域将自动略过.
  157. '虽然使用代码"Intersect(当前单元格.EntircColumn,ActiveWindow.VisibleRange)"也可以将范围限制在当前行的可见区域,
  158. '不过当用户使用冻结空格功能后,就会出现问题。对它做了进一步限制,防止出现BUG。

  159. '5、复制与剪切
  160.     '当使用着色工具后,系统的复制和剪切功能将全部失效,为了杜绝此问题,需要配全"复制对象"的自定义函数应用
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2022-11-16 13:48 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-9-28 07:16 , Processed in 0.044244 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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