标签:strlen color 直接 初始 dex == 颜色 lca gif
实现的效果见视频。
使用方法:
说明:
#SingleInstance Force F12::ExitApp F9:: event_highlightRowByColumnValue() return ;根据当前列的值高亮表内【行】 ;要求有标题行 event_highlightRowByColumnValue() { idName := A_ThisFunc xl := ox() ac := xl.ActiveCell ;NOTE 记录关键列号,因为 target 不可靠 cKey := ac.column ;定义颜色顺序 ColorIndex arrColor := [33,34,35,36,37,38,39,40,41] ;开启/关闭事件 if !Events_Workbook.objEvent.haskey(idName) { highlightRowByColumn(ac) ;开启事件前直接运行一次 new Events_Workbook(xl.ActiveWorkbook, idName, "Change", func("highlightRowByColumn")).start() ;用内部函数也没问题 } else if (Events_Workbook.objEvent[idName].wb.name = xl.ActiveWorkbook.name) ;当前工作表 = 事件监控工作表 Events_Workbook.objEvent[idName].stop() ;实例没保存到变量,用此方法引用 highlightRowByColumn(target:="") { ;获取数据区域(不含标题行) try rngData := target.ListObject.DataBodyRange catch { rngCR := target.CurrentRegion rngData := rngCR.offset(1).resize(rngCR.rows.count-1) } ;关键列区域 rngKeyCol := rngData.columns(cKey-rngData.column+1) ;判断修改值的单元格是否在 rngKeyCol 内 if !isobject(xl.intersect(target, rngKeyCol)) return else if (target.columns.count > 1) ;多列 target := xl.intersect(target, rngKeyCol) ;单个单元格且为空值,则不处理 if (target.cells.count == 1 & !strlen(target.value)) return xl.ScreenUpdating := false arrV := rngKeyCol.value ;获取当前列的值 idx := 1 ;颜色序号 cnt := 1 ;同值行数 _v := arrV[1,1] ;用来判断是否同个值 rngRowStart := rngData.rows(1) ;当前高亮的第1行 loop(arrV.MaxIndex(1)-1) ;从第2行开始循环 { if (arrV[A_Index+1,1] != _v) { rngRowStart.resize(cnt).interior.ColorIndex := arrColor[idx] ;初始化 rngRowStart := rngData.rows(A_Index+1) _v := arrV[A_Index+1,1] cnt := 1 ;记录下一颜色序号 idx++ if (idx > arrColor.length()) idx := 1 } else cnt++ } ;NOTE 执行最后一类数据的高亮 rngRowStart.resize(cnt).interior.ColorIndex := arrColor[idx] xl.ScreenUpdating := true } } ; https://autohotkey.com/board/topic/69847-com-events-using-ByRef-parms/?p=442260 class Events_Workbook { static objEvent := {} ;保存事件的所有信息供外部使用,以传入的 event 为key ;NOTE wb为事件的载体,其他工作簿单独事件逻辑 ;用 idName 区别各功能 ;同事件可满足多个需求 __new(wb, idName, event, funcObj:="", data:="") { this.tipsLevel := 19 this.idName := idName this.event := event ;监控的事件名称,多事件可用数组 this.wb := wb ;实例要用,用 objEvent 提取太麻烦 this.funcObj := funcObj ;TODO 是否要区分不同事件 this.data := data ;其他传入的值 } ;所有事件+方法都会运行 ;evtThis为 Sheet+事件名,args[1]=target __call(evtThis, args*) { ;tooltip(evtThis) if (evtThis = this.event || substr(evtThis,6) = this.event) ;筛选事件名称(从第6个字符开始提取是为了删除 Sheet 前缀) this.funcObj.call(args*) ;else if isobject(this.event) ;暂时没用 ;{ ;for _, evt in this.event ;{ ;if (evtThis = evt || substr(evtThis,6) = evt) ;筛选事件 ;{ ;this.funcObj.call(args*) ;return ;} ;} ;} } ;TODO 监控工作表和工作簿,分别怎么实现 start() { Events_Workbook.objEvent[this.idName] := this ;NOTE 保存实例,外部获取信息和 stop 用,这样外面不需要保存实例变量 ComObjConnect(this.wb, this) this.tipsShow("start") } stop() { ComObjConnect(this.wb) Events_Workbook.objEvent.delete(this.idName) this.tipsShow("stop") this := "" ;ObjRelease 会出错 } list() { return Events_Workbook.objEvent } ;事件结束会关闭显示 tipsShow(str) { if !isobject(this.data) { tooltip(str,,, this.tipsLevel) SetTimer(func("tooltip").bind(,,, this.tipsLevel), -1000) } else { tooltip(this.data.tipStr,,, this.tipsLevel) if this.data.haskey("tipTime") { if this.data.tipTime SetTimer(func("tooltip").bind(,,, this.tipsLevel), -this.data.tipTime) } else SetTimer(func("tooltip").bind(,,, this.tipsLevel), -1000) } } } ox(winTitle:="ahk_class XLMAIN") { ctlID := ControlGetHwnd("EXCEL71", winTitle) if !ctlID ExitApp if dllcall("oleacc\AccessibleObjectFromWindow", "ptr",ctlID, "uint",4294967280, "ptr",-VarSetCapacity(IID,16)+NumPut(0x46000000000000C0,NumPut(0x0000000000020400,IID,"int64"),"int64"), "ptr*",pacc) = 0 win := ComObject(9, pacc, 1) loop { try xl := win.application catch ControlSend("{escape}", "EXCEL71", winTitle) } until !!xl return xl }
AutoHotkey监控Excel事件应用(1)---根据当前列的值高亮行
标签:strlen color 直接 初始 dex == 颜色 lca gif
原文地址:https://www.cnblogs.com/hyaray/p/13171936.html