ListView 中复制某一列的数据
本帖最后由 zbezj 于 2014-11-30 00:01 编辑默认使用 _ArrayDisplay($aArray)函数生成的 列表视图,只能复制行。现在我想复制某一列的数值,请问怎么修改代码? 谢谢。
或者,把这些所有的数据,按照行列,复制到Excel中。
http://www.autoitx.com/thread-28506-1-1.html 本帖最后由 user3000 于 2014-11-30 16:46 编辑
1~~~~~~~~~~~~~~~~~
重新编辑帖子,简化其内容.
请稳步6楼参观源代码. 回复zbezj
改自原有的_ArrayDisplay函数
增加你要的列复制功能.
~~周末有丁点时间,权当做点练 ...
user3000 发表于 2014-11-30 11:08 http://www.autoitx.com/images/common/back.gif
厉害啊!非常感谢!
不过鼠标选的时候,要是能把这一列选中就更完美了。 本帖最后由 user3000 于 2014-11-30 16:48 编辑
2~~~~~~~~~~~~~~~
重新编辑帖子,简化其内容.
请稳步6楼参阅源代码 回复 4# zbezj
向 netegg 及 3mile 两位老大致敬,参考了他们的相关帖子可以实现这类显示效果了.
如果还发现什么问题,请继续跟贴.
#include<array.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
Local $avArray = [["JPM", "Holger", "Jon", "Larry", "Jeremy"],["Valik", "Cyberslug", "Nutster", "JdeB", "Tylo"],["JPM2", "Holger2", "Jon2", "Larry2", "Jeremy2"]]
_ArrayDisplayX($avArray)
Func _ArrayDisplayX(Const ByRef $avArray, $sTitle = "ListView列表查看数组", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "", $sReplace = "|", $sHeader = "")
If Not IsArray($avArray) Then Return SetError(1, 0, 0)
; Dimension checking
Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
If $iDimension > 2 Then Return SetError(2, 0, 0)
; Separator handling
If $sSeparator = "" Then $sSeparator = Chr(124) ;Check the separator to make sure it's not used literally in the array
If _ArraySearch($avArray, $sSeparator, 0, 0, 0, 1) <> -1 Then
For $x = 1 To 255
If $x >= 32 And $x <= 127 Then ContinueLoop
Local $sFind = _ArraySearch($avArray, Chr($x), 0, 0, 0, 1)
If $sFind = -1 Then
$sSeparator = Chr($x)
ExitLoop
EndIf
Next
EndIf
; Declare variables
Local $vTmp, $iBuffer = 4094 ; AutoIt max item size
Local $iColLimit = 250
Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparator)
; Swap dimensions if transposing
If $iSubMax < 0 Then $iSubMax = 0
If $iTranspose Then
$vTmp = $iUBound
$iUBound = $iSubMax
$iSubMax = $vTmp
EndIf
; Set limits for dimensions
If $iSubMax > $iColLimit Then $iSubMax = $iColLimit
If $iItemLimit < 1 Then $iItemLimit = $iUBound
If $iUBound > $iItemLimit Then $iUBound = $iItemLimit
; Set header up
If $sHeader = "" Then
$sHeader = "Row" ; blanks added to adjust column size for big number of rows
For $i = 0 To $iSubMax
$sHeader &= $sSeparator & "Col " & $i
Next
EndIf
; Convert array into text for listview
Local $avArrayText[$iUBound + 1]
For $i = 0 To $iUBound
$avArrayText[$i] = "[" & $i & "]"
For $j = 0 To $iSubMax
; Get current item
If $iDimension = 1 Then
If $iTranspose Then
$vTmp = $avArray[$j]
Else
$vTmp = $avArray[$i]
EndIf
Else
If $iTranspose Then
$vTmp = $avArray[$j][$i]
Else
$vTmp = $avArray[$i][$j]
EndIf
EndIf
; Add to text array
$vTmp = StringReplace($vTmp, $sSeparator, $sReplace, 0, 1)
; Set max buffer size
If StringLen($vTmp) > $iBuffer Then $vTmp = StringLeft($vTmp, $iBuffer)
$avArrayText[$i] &= $sSeparator & $vTmp
Next
Next
; GUI Constants
Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 0x66
Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 0x40
Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 0x0200
Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 0x2
Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 0x4
Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3
Local Const $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH = (0x1000 + 29)
Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4)
Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20
Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1
Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8
Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200
Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000
Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000
Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000
; Set interface up
Local $iWidth = 800, $iHeight = 600
Local $hGUI = GUICreate($sTitle, $iWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
Local $aiGUISize = WinGetClientSize($hGUI)
Global $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize, $aiGUISize - 50, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS)
Local $hCopy = GUICtrlCreateButton('复制行(请先点击该行)', 3, $aiGUISize - 46, $aiGUISize - 6, 20)
Local $vCopy = GUICtrlCreateButton('复制列(请先点击该列名)', 3, $aiGUISize - 23, $aiGUISize - 6, 20)
GUICtrlSetState($hCopy, $gui_disable)
GUICtrlSetState($vCopy, $gui_disable)
GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
GUICtrlSetResizing($hCopy, $_ARRAYCONSTANT_GUI_DOCKLEFT + $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
GUICtrlSetResizing($vCopy, $_ARRAYCONSTANT_GUI_DOCKLEFT + $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES)
GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT)
GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE)
; 从数组添加列表项目
Local $iItem_Click = 0, $iColumn = 0, $nMsg, $iItem_Tmp
Global $hGui_sel = -1, $aPos = 0, $aRect = 0
Local Const $iItem_First = $vCopy + 1
For $i = 0 To $iUBound
$iItem_Tmp = GUICtrlCreateListViewItem($avArrayText[$i], $hListView)
Next
Local Const $iItem_Last = $iItem_Tmp
; 调整窗体大小
$iWidth = 0
For $i = 0 To $iSubMax + 1
$iWidth += GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH, $i, 0)
Next
If $iWidth < 250 Then $iWidth = 230
$iWidth += 20
If $iWidth > @DesktopWidth Then $iWidth = @DesktopWidth - 100
WinMove($hGUI, "", (@DesktopWidth - $iWidth) / 2, Default, $iWidth)
GUISetState(@SW_SHOW, $hGUI);显示窗体
While 1
$aMsg = GUIGetMsg(1)
$nMsg = $aMsg
Switch $nMsg
Case $_ARRAYCONSTANT_GUI_EVENT_CLOSE
ExitLoop
Case $GUI_EVENT_PRIMARYDOWN
If $aMsg = $hGui_sel Then
_GUIDelete()
$iItem_Click = _GUICtrlListView_GetHotItem($hListView)
_GUICtrlListView_SetItemSelected($hListView, $iItem_Click)
$iItem_Click += $iItem_First
EndIf
Case $hCopy
Local $sClip = ""
$sClip = StringRegExpReplace(GUICtrlRead($iItem_Click), '^.+?\' & $sSeparator & '|\' & $sSeparator & '$', '')
$sClip = StringReplace($sClip, $sSeparator, @TAB)
;MsgBox(0, '', $sClip)
ClipPut($sClip)
Case $vCopy
Local $sPattern = '^((?:.+?\' & $sSeparator & '){' & $iColumn & '})([^' & $sSeparator & ']+).*'
Local $sClip = '', $sTmp
For $i = 0 To $iUBound
$sTmp = StringRegExpReplace($avArrayText[$i], $sPattern, '\2')
If @extended Then $sClip &= $sTmp & @CRLF
Next
;MsgBox(0, '', $sClip);
ClipPut($sClip)
Case $hListView
GUICtrlSetData($hCopy, '复制行(请先点击该行)')
GUICtrlSetState($hCopy, $gui_disable)
GUICtrlSetState($iItem_Click, $GUI_NOFOCUS)
$iItem_Click = 0
_GUIDelete()
$iColumn = GUICtrlGetState($hListView)
If $iColumn Then
GUICtrlSetState($vCopy, $gui_enable)
GUICtrlSetData($vCopy, '复制第' & $iColumn & '列')
$aPos = WinGetPos(GUICtrlGetHandle($hListView))
$aRect = _GUICtrlListView_GetSubItemRect($hListView, 0, $iColumn)
If Not IsArray($aRect) Or Not IsArray($aPos) Then ContinueLoop
;ConsoleWrite($aRect & @TAB & $aRect & @TAB & $aRect & @TAB & $aRect & @CRLF)
Local $iW = $aRect - $aRect, $iY = $aRect - $aRect
$hGui_sel = GUICreate('', $iW, $iY * ($iItem_Last - $iItem_First + 1), $aPos + $aRect + 2, $aPos + $aRect, 0x80000000, -1, $hGUI)
GUISetBkColor(0x0a246a, $hGui_sel)
WinSetTrans($hGui_sel, '', 100)
GUISetState()
GUIRegisterMsg(0x0003, "WM_MOVE");$WM_MOVE
WinActivate($hGUI)
EndIf
Case $iItem_First To $iItem_Last
_GUIDelete()
$iItem_Click = $nMsg
GUICtrlSetState($hCopy, $gui_enable)
GUICtrlSetData($hCopy, '复制第' & ($iItem_Click - $vCopy) & '行')
$iColumn = 0
GUICtrlSetState($vCopy, $gui_disable)
GUICtrlSetData($vCopy, '复制列(请先点击该列名)')
EndSwitch
WEnd
GUIDelete($hGUI)
Opt("GUIOnEventMode", $iOnEventMode)
Opt("GUIDataSeparatorChar", $sDataSeparatorChar)
Return 1
EndFunc ;==>_ArrayDisplayX
Func _GUIDelete()
If Not $hGui_sel Then Return
GUIRegisterMsg(0x0003, '')
GUIDelete($hGui_sel)
$hGui_sel = 0
$aPos = 0
$aRect = 0
EndFunc ;==>_GUIDelete
Func WM_MOVE($hWnd, $Msg, $wParam, $lParam)
$aPos = WinGetPos(GUICtrlGetHandle($hListView))
If Not IsArray($aRect) Or Not IsArray($aPos) Then Return
WinMove($hGui_sel, "", $aPos + $aRect + 2, $aPos + $aRect)
EndFunc ;==>WM_MOVE
回复 4# zbezj
按复制单列你的要求,不应该有鼠标框选的情况.
所以只有点击列的表头时,才显示该列的"框选"效果了. 这个不错, 收藏了
页:
[1]