Въведение.
Ние сме запознати с операциите Drag and Drop на TreeView Control, в Ms-Access, който пренарежда възлите. Всички основни записи за контролните възли на Treeview идват от една таблица за достъп. Винаги актуализираме ParentID на изходния възел стойност на полето, със стойността на ID на целевия възел в същия запис в таблицата, за да направите промяната на позицията на контролата TreeView. Записите не се преместват физически никъде.
Тук, с добавянето на ListView Control заедно с TreeView Control, планираме да работим с две различни таблици за достъп.
- lvCategory – Код и описание на категорията.
- lvПродукти – Продукти по категории.
По този начин е по-лесно да се разбере връзката между двете таблици. Какви промени трябва да направим и къде, когато един продукт (елемент ListView) се премести от една категория в друга в контролата TreeView.
lvCategory Таблицата за достъп има 20 записа за възлите на TreeView и lvProducts Таблицата има 45 за контролата ListView. Един или повече записи в таблицата с продукти са пряко свързани с продуктова категория в таблицата с категории. Връзката между тях е актуализирана със стойността на полето за идентификатор на категория (CID) в ParentID на таблицата с продукти поле, така че промяната на категорията на продукта да се отрази незабавно върху ListView Control.
Таблицата с демонстрационни данни е взета от примерната база данни на Microsoft Access Northwind.accdb и разделена на две части.
Въз основа на стойността на полето ParentID на записите на lvProduct бихме могли да филтрираме и изброим всички свързани продуктови артикули в контролата ListView, когато възел на категория бъде избран в контролата TreeView.
Теми, които разгледахме досега.
Следват основните теми на TreeView , Списък с изображения , ImageCombo, и ListView Контроли, които разгледахме досега в MS-Access:
- Урок за контрол на Microsoft TreeView
- Създаване на меню за достъп с TreeView Control
- Присвояване на изображения към TreeView Control
- Присвояване на изображения към TreeView Control-2
- TreeView Control Маркирайте отметка за добавяне на изтриване на възли
- DreeView ImageCombo падащо меню за достъп
- Пренаредете възлите на TreeView чрез плъзгане и пускане
- ListView Control с MS-Access TreeView
Задачата за плъзгане на ListView.
Що се отнася до операцията Drag and Drop на ListView, това е просто упражнение, сравняващо същия метод само в TreeView Control. Тъй като действието Drag Drop включва както TreeView, така и ListView контроли, ние използваме същата процедура за събитие TreeView0_OLEDragDrop() с някакъв прост VBA код.
Продуктовите елементи, изброени в контролата ListView, принадлежат на текущия елемент от категорията, избран в контролата TreeView.
Потребителят избира конкретен продукт от контролата ListView, ако той/тя смята, че принадлежи към друг артикул от категория, след това го плъзнете и пуснете върху целевия елемент от категорията на TreeViewCcontrol.
Преместеният продукт ListView ще бъде добавен към списъка с елементи, които принадлежат към променената категория. Стойността на полето ParentID на записа на продукта се актуализира с целевия идентификационен номер на запис за категория (стойност на CID).
Това е само еднопосочно действие, винаги премествайте елемента ListView от една категория и го пускайте на различен възел на категория в контролата TreeView.
Демонстрационният формуляр за достъп до ListView с плъзгане и пускане frmListViewDrag’ Пробно изпълнение Изображението на екрана е дадено по-долу:
На горното изображение Напитките Избрана е категория в TreeView. Продуктите принадлежат към категорията Напитки са изброени в ListView Control.
Изгледът на дизайна на горния формуляр:
Списъкът с имена на контроли във формуляра е, както е даден по-долу:
- Контрол на TreeView:TreeView0
- Контрол на ListView:ListView0
- Контрол за списък на изображения:ImageList3
- Команден бутон:cmdClose
VBA кодът на frmListViewDrag Модул за класове:
Option Compare Database
Option Explicit
Dim tv As MSComctlLib.TreeView
Dim lvList As MSComctlLib.ListView
Dim imgList As MSComctlLib.ImageList
Const Prfx As String = "X"
Private Sub Form_Load()
Dim db As DAO.Database
Dim tbldef As TableDef
Set tv = Me.TreeView0.Object
tv.Nodes.Clear
Set imgList = Me.ImageList3.Object
With tv
.Font.Size = 9
.Font.Name = "Verdana"
.ImageList = imgList 'assign preloaded imagelist control
End With
Set lvList = Me.ListView0.Object
lvList.ColumnHeaders.Clear
lvList.ListItems.Clear
lvList.Icons = imgList
Set db = CurrentDb
Set tbldef = db.TableDefs("lvProducts")
'Initialize ListView & Column Headers Property Values
With lvList
.ColumnHeaderIcons = imgList
.Font.Size = 9
.Font.Name = "Verdana"
.Font.Bold = False
'ColumnHeaders.Add() Syntax:
'lvList.ColumnHeaders.Add Index, Key, Text, Width, Alignment, Icon
'Alignment: 0 - Left, 1 - Right, 2 - Center
.ColumnHeaders.Add 1, , tbldef.Fields(1).Name, 2600, 0, 5
.ColumnHeaders.Add 2, , tbldef.Fields(3).Name, 2600, 0, 5
.ColumnHeaders.Add 3, , tbldef.Fields(4).Name, 1440, 1, 5
End With
Set db = Nothing
Set tbldef = Nothing
LoadTreeView 'Create TreeView Nodes
End Sub
Private Sub LoadTreeView()
Dim Nod As MSComctlLib.Node
Dim firstCatID As Long
Dim strCategory As String
Dim strCatKey As String
Dim strBelongsTo As String
Dim strSQL As String
Dim db As DAO.Database
Dim rst As DAO.Recordset
'Initialize treeview nodes
tv.Nodes.Clear
'Initialize Listview nodes
While lvList.ListItems.Count > 0
lvList.ListItems.Remove (1)
Wend
strSQL = "SELECT lvCategory.CID, lvCategory.Category, "
strSQL = strSQL & "lvcategory.BelongsTo FROM lvCategory ORDER BY lvCategory.CID;"
Set db = CurrentDb
Set rst = db.OpenRecordset(strSQL, dbOpenSnapshot)
If Not rst.BOF And Not rst.EOF Then
rst.MoveFirst
firstCatID = rst!CID
Else
Exit Sub
End If
' Populate all Records as Rootlevel Nodes
Do While Not rst.BOF And Not rst.EOF
strCatKey = Prfx & CStr(rst!CID)
strCategory = rst!Category
Set Nod = tv.Nodes.Add(, , strCatKey, strCategory, 1, 2)
Nod.Tag = rst!CID
rst.MoveNext
Loop
'In the second pass of the the same set of records
'Move Child Nodes under their Parent Nodes
rst.MoveFirst
Do While Not rst.BOF And Not rst.EOF
strBelongsTo = Nz(rst!BelongsTo, "")
If Len(strBelongsTo) > 0 Then
strCatKey = Prfx & CStr(rst!CID)
strBelongsTo = Prfx & strBelongsTo
strCategory = rst!Category
Set tv.Nodes.Item(strCatKey).Parent = tv.Nodes.Item(strBelongsTo)
End If
rst.MoveNext
Loop
rst.Close
' Populate ListView Control with Product details
' of the first Category Item
LoadListView firstCatID
End Sub
Private Sub LoadListView(ByVal CatID)
Dim strProduct As String
Dim strPKey As String
Dim intcount As Integer
Dim tmpLItem As MSComctlLib.ListItem
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
' Initialize ListView Control
While lvList.ListItems.Count > 0
lvList.ListItems.Remove (1)
Wend
strSQL = "SELECT lvProducts.* FROM lvProducts "
strSQL = strSQL & "WHERE (lvProducts.ParentID = " & CatID & ") "
strSQL = strSQL & "ORDER BY lvProducts.[Product Name];"
'Open filtered Products List for selected category
Set db = CurrentDb
Set rst = db.OpenRecordset(strSQL, dbOpenSnapshot)
Do While Not rst.BOF And Not rst.EOF
intcount = intcount + 1
strProduct = rst![Product Name]
strPKey = Prfx & CStr(rst!PID)
'List Item Add() Syntax:
'lvList.ListItems.Add Index,Key,Text,Icon,SmallIcon
Set tmpLItem = lvList.ListItems.Add(, strPKey, strProduct, , 3) 'first column
lvList.ForeColor = vbBlue
'List second column sub-item Syntax:
'tmpLItem.ListSubItems.Add Column - Index, Key, Text, ReportIcon, ToolTipText
tmpLItem.ListSubItems.Add 1, strPKey & CStr(intcount), Nz(rst![Quantity Per Unit], ""), 6
'List third column sub-item
tmpLItem.ListSubItems.Add 2, strPKey & CStr(intcount + 1), Format(rst![list Price], "0.00"), 6, "In Local Currency."
rst.MoveNext
Loop
Set db = Nothing
Set rst = Nothing
If intcount > 0 Then lvList.ListItems(1).Selected = True
End Sub
Private Sub TreeView0_NodeClick(ByVal Node As Object)
Dim Cat_ID As String
Cat_ID = Node.Tag
LoadListView Cat_ID
End Sub
Private Sub TreeView0_OLEStartDrag(Data As Object, AllowedEffects As Long)
Set tv.SelectedItem = Nothing
End Sub
Private Sub TreeView0_OLEDragOver(Data As Object, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, State As Integer)
On Error GoTo TreeView0_OLEDragOver_Err
Dim nodSelected As MSComctlLib.Node
Dim nodOver As MSComctlLib.Node
If tv.SelectedItem Is Nothing Then
'Select a node if one is not selected
Set nodSelected = tv.HitTest(X, Y)
If Not nodSelected Is Nothing Then
nodSelected.Selected = True
End If
Else
If tv.HitTest(X, Y) Is Nothing Then
'do nothing
Else
'Highlight the node the mouse is over
Set nodOver = tv.HitTest(X, Y)
Set tv.DropHighlight = nodOver
End If
End If
TreeView0_OLEDragOver_Exit:
Exit Sub
TreeView0_OLEDragOver_Err:
MsgBox Err & " : " & Err.Description, vbInformation, "TreeView0_OLEDragOver()"
Resume TreeView0_OLEDragOver_Exit
End Sub
Private Sub TreeView0_OLEDragDrop(Data As Object, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim tv_nodSource As Node
Dim tv_nodTarget As Node
Dim strtv_ParentKey As String
Dim strtv_TargetKey As String
Dim strListItemKey As String
Dim strSQL As String
Dim vCatID As Long
Dim lngPID As Long
On Error GoTo TreeView0_OLEDragDrop_Err
'Get the source/destination Nodes
Set tv_nodSource = tv.SelectedItem
Set tv_nodTarget = tv.HitTest(X, Y)
If Not tv_nodTarget Is Nothing Then
strtv_ParentKey = tv_nodSource.Key
strtv_TargetKey = tv_nodTarget.Key
If strtv_ParentKey = strtv_TargetKey Then Exit Sub
'Extract ListItem Key
strListItemKey = lvList.SelectedItem.Key
'extract Category Record CID Value
'and ListItem Product ID Key
vCatID = Val(Mid(tv_nodTarget.Key, 2))
lngPID = Val(Mid(strListItemKey, 2))
'UPDATE lvProducts Table
strSQL = "UPDATE lvProducts SET ParentID = " & vCatID & _
" WHERE PID = " & lngPID
CurrentDb.Execute strSQL, dbFailOnError
Set tv.DropHighlight = Nothing
tv_nodSource.Selected = True
'Rebuild ListView Nodes
TreeView0_NodeClick tv_nodSource
Else ' Invalid Target location
MsgBox "The destination is invalid!", vbInformation
End If
TreeView0_OLEDragDrop_Exit:
Exit Sub
TreeView0_OLEDragDrop_Err:
MsgBox Err & " : " & Err.Description, vbInformation, "TreeView0_OLEDragDrop()"
Resume TreeView0_OLEDragDrop_Exit
End Sub
Private Sub TreeView0_OLECompleteDrag(Effect As Long)
Set tv.DropHighlight = Nothing
End Sub
Private Sub cmdClose_Click()
DoCmd.Close
End Sub
Познатите VBA кодови сегменти.
В Form_Load() Процедура за събитие, ние инициализираме контролите TreeVew, ListView, ImageList. Той създава Заглавия на колони на контролата ListView, преди да попълните елементи от списъка в контролата Listview. В края на тази подпрограма извикаме подпрограмата LoadTreeView().
LoadTreeView() подпрограмата попълва възлите на категориите на продуктите в контролата TreeView със записите от lvCategory Таблица. Зареждането на възли в TreeView Control е процес в две стъпки. Защо е така, вместо да го правим наведнъж? Този аспект е обяснен подробно на по-ранна страница, 7-ма връзка в списъка с връзки дайте по-горе, ако искате да го прегледате. Повтарянето на всички тук може да не е подходящо.
В края на горната подпрограма LoadListView() подпрограмата е извикана с CID стойност на първия запис на категория 1 като параметър.
Записите на продукта със стойност на полето ParentID 1 са филтрирани и изброени в контролата ListView. Тази процедура беше обяснена подробно в публикацията от миналата седмица, 8-ми елемент, сред списъка с връзки, даден по-горе.
Подпрограмите за действие с плъзгане и пускане.
Следните подпрограми, свързани с действието Drag and Drop, ще бъдат изпълнени автоматично в реда, в който са представени по-долу:
- TreeView0_OLEStartDrag()
- TreeView0_OLEDragOver()
- TreeView0_OLEDragDrop()
- TreeView0_OLECompleteDrag()
Първата и последната подпрограми инициализират участващите възли и съответно нулират състоянието им в края.
Втората, OLEDragOver() подпрограма работи като MouseMove Event Procedure и проследява движението на мишката по време на операцията с плъзгане и пускане. Той подчертава NodeText, когато мишката е над възел и проследява траекторията му, докато левият бутон на мишката не бъде освободен.
Самият код на процедурата TreeView0_OLEDragDrop() е изброен по-долу.
Private Sub TreeView0_OLEDragDrop(Data As Object, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim tv_nodSource As Node
Dim tv_nodTarget As Node
Dim strtv_ParentKey As String
Dim strtv_TargetKey As String
Dim strListItemKey As String
Dim strSQL As String
Dim vCatID As Long
Dim lngPID As Long
On Error GoTo TreeView0_OLEDragDrop_Err
'Get the source/destination Nodes
Set tv_nodSource = tv.SelectedItem
Set tv_nodTarget = tv.HitTest(X, Y)
If Not tv_nodTarget Is Nothing Then
strtv_ParentKey = tv_nodSource.Key
strtv_TargetKey = tv_nodTarget.Key
If strtv_ParentKey = strtv_TargetKey Then Exit Sub
'Extract ListItem Key
strListItemKey = lvList.SelectedItem.Key
'extract Category Record CID Value
'and ListItem Product ID Key
vCatID = Val(Mid(tv_nodTarget.Key, 2))
lngPID = Val(Mid(strListItemKey, 2))
'UPDATE lvProducts Table
strSQL = "UPDATE lvProducts SET ParentID = " & vCatID & _
" WHERE PID = " & lngPID
CurrentDb.Execute strSQL, dbFailOnError
Set tv.DropHighlight = Nothing
tv_nodSource.Selected = True
'Rebuild ListView Nodes
TreeView0_NodeClick tv_nodSource
Else ' Invalid Target location
MsgBox "The destination is invalid!", vbInformation
End If
TreeView0_OLEDragDrop_Exit:
Exit Sub
TreeView0_OLEDragDrop_Err:
MsgBox Err & " : " & Err.Description, vbInformation, "TreeView0_OLEDragDrop()"
Resume TreeView0_OLEDragDrop_Exit
End Sub
Действие с плъзгане стъпка по стъпка.
Процедурата TreeView0_OLEDragDrop() се изпълнява веднага след освобождаването на левия бутон на мишката, за да завърши действието Drop. В началото на кода активните и препратките на Target TreeView Node са запазени в tv_nodSource и tv_nodTarget обектни променливи съответно.
След това извършваме проверка дали ListItem е изпуснат на валиден TreeView възел или не. Ако бъде пуснат на същия възел на категория източник или на празна област на TreeView Control, тогава тези ходове не са валидни. Ако е пуснат в празна област на TreeView Control, тогава tv_nodTarget обектната променлива ще съдържа стойността Нищо. В такъв случай е показва съобщение и излиза от програмата.
След това ключовите стойности на TreeView Source и Target Node се записват в две низови променливи. Ако и двата ключа са еднакви, тогава ListItem се плъзга и пуска на собствения си родителски възел (възел на категория) в контролата TreeView. Изпълнението на програмата е прекратено от продължаване.
Ако и двата ключа са различни, тогава е време да актуализирате промяната в ParentID на Product Record поле с CID на записа за целева категория Кодирайте и опреснете елементите на ListView.
Ключовата стойност на избрания ListItem (PID стойност на полето) е запазена в strListItemKey Низова променлива.
Действителният CID на записа на категорията стойността на полето е извлечена от целевия възел чрез премахване на стойността на префикса X и записана в променлива vCatID . Това е стойността, която ще актуализираме в полето ParentID на записа на продукта, за да поставим ListItem в новата категория.
По същия начин ключовата PID стойност на продукта на избрания елемент от списъка е извлечена и записана в променлива lngPID . Това е използвано като критерий за филтриране и избор на този конкретен запис на продукт за актуализиране на полето ParentID с vCatID .
АКТУАЛИЗИРАНЕ SQL заявка е създадена за филтриране на записа, като се използва lngPID Кодирайте като критерии, за да филтрирате записа на продукта и да актуализирате vCatID Стойност в P arentID поле.
Изпълнение метод на Currentdb е извикан с SQL и актуализира промяната.
Акцентът на възела е нулиран до изходния възел.
След това подпрограмата TreeView0_NodeClick() е извикана с tv_nodSource като параметър за отразяване на промяната в контролата ListView.
Затваряне Щракването върху бутона ще затвори формуляра.
Изтеглете демо база данни.
Можете да изтеглите демо базата данни, да правите пробни версии и да изучавате VBA кода.
ЖЕЛАЯ ВИ МНОГО ЧЕСТИТА НОВА ГОДИНА.
ОБРАВЯНЕ НА СЪБИТИЯ MS-ACCESS
- Включва модула за клас на MS-Access
- Събития и дефиниране на вашите собствени събития
- Раздел на текстовото поле с комбиниран списък на Withevents
- Достъп до масиви и събития за контрол на формуляр
- Достъп до масиви за контрол на формуляри и събитие-2
- Достъп до масиви за контрол на формуляри и събитие-3
- Събития в модул за клас за подформуляр
- Събития в модул и данни за клас
- Събития и приемник на събития за отчет за достъп
- Скриване на събития и скриване на реда за отчет
- Събития и открояване на ред в отчет
- Изключва текстовото поле и командния бутон
- Команден бутон на текстовото поле Withevents
- Събития и всички видове контрол на формуляра