копирование данных из ЛистБокса в КомбоБокс

  • Автор темы Alex77777
  • Дата начала
A

Alex77777

Гость
#1
есть код, но он работает только если Лист- и комбоБоксы находятся на одной форме. Вопрос:как сделать так чтобы данные из листбокса формы1 копировались в комбобокс формы2.

Private Declare Function SendMessageStr Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Sub Command1_Click()
Dim success As Long
success = CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End Sub

Private Function CopyListToCombo(source As ListBox, target As ComboBox) As Long
Dim c As Long
Const LB_GETCOUNT = &H18B
Const LB_GETTEXT = &H189
Const CB_GETCOUNT = &H146
Const CB_ADDSTRING = &H143
Dim numitems As Long
Dim sItemText As String * 255
numitems = SendMessageLong(source.hWnd, LB_GETCOUNT, 0&, 0&)
If numitems > 0 Then
For c = 0 To numitems - 1
Call SendMessageStr(source.hWnd, LB_GETTEXT, c, ByVal sItemText)
Call SendMessageStr(target.hWnd, CB_ADDSTRING, 0&, ByVal sItemText)
Next
End If
numitems = SendMessageLong(target.hWnd, CB_GETCOUNT, 0&, 0&)
CopyListToCombo = numitems
End Function

Private Sub Form1_Load()
List1.AddItem "1"
List1.AddItem "2"
List1.AddItem "3"
End Sub

этот код работает в пределах одной формы

Пытался сделать так:
в Form1

Public success As Long 'глобальная переменная
Private Declare Function SendMessageStr Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Function CopyListToCombo(source As ListBox, target As ComboBox) As Long
Dim c As Long
Const LB_GETCOUNT = &H18B
Const LB_GETTEXT = &H189
Const CB_GETCOUNT = &H146
Const CB_ADDSTRING = &H143
Dim numitems As Long
Dim sItemText As String * 255
numitems = SendMessageLong(source.hWnd, LB_GETCOUNT, 0&, 0&)
If numitems > 0 Then
For c = 0 To numitems - 1
Call SendMessageStr(source.hWnd, LB_GETTEXT, c, ByVal sItemText)
Call SendMessageStr(target.hWnd, CB_ADDSTRING, 0&, ByVal sItemText)
Next
End If
numitems = SendMessageLong(target.hWnd, CB_GETCOUNT, 0&, 0&)
CopyListToCombo = numitems
End Function

а в Form2
Private Sub Form1_Load()
Dim success As String
success = Form1.success
cboExpert.AddItem success
End Sub

в итоге в комбобокс Form2 у меня добавляется только цифра равная кол-ву введенных строк в листбокс Form1.

кто знает в чем здесь запинка, подскажите как ее исправить.

при этом нужно чтобы при нажатии на клавишу "очистить" листбокса на Form1 очищался комбобокс на Form2
 
T

Tanya

Гость
#2
используй полные имена контролов, то есть со ссылкой на родительскую форму

Допустим List1 и Command1 на форме Form1, а Combo1 на Form2
тогда

Private Sub Command1_Click()
Dim success As Long
success = CopyListToCombo(List1, Form2.Combo1)
If success Then Form2.Combo1.ListIndex = 0

End Sub

ну и соответственно очистка обоих элементов:
Form1.List1.Clear
Form2.Combo1.Clear
 
A

Alex77777

Гость
#3
все работает, только вот какая штука, нажимая на кнопку копировать в комбобокс - открывается сразу Form2, а мне нужно чтобы при нажатии кнопки копировать Form2 не открывалась, а данные из листбокса копировались в комбокосе были при каждом открытии Form2. то есть сначала я открываю Form1, вношу в листбокс данные, затем открываю Form2, и в комбобоксе д.б. данные, затем открываю вторую Form2, третью Form2 и т.д.

пробовал вставить
Dim success As String
success = frmMyInstallations.success
cboExpert.AddItem success
success = CopyListToCombo(frmMyInstallations.lstFIO, frmNewVisit.cboExpert)
If success Then frmNewVisit.cboExpert.ListIndex = 0

в этом случае пишет ошибка компиляции: Sub or Function not defined

по другому пробовал в Form2_Load() весь код запихать, но он ругается, пишет: "обнаружено не однозначное имя SendMessageLong" (подсвечивает "CopyListToCombo" в Form2).
 
T

Tanya

Гость
#4
Конечно нужно список combo заполнять при каждой загрузке окна Form2

При этом функцию CopyListToCombo лучше сделать Public и разместить в отдельном модуле,
где так же продекларировать только 1 раз все SendMessage
(тут уже на твое усмотрение как она будет использоваться: как Private или Public)

А затем в событии Form_Load формы Form2 использовать CopyListToCombo

Кнопка копирования в комбобокс, скорее всего не нужна, поскольку, действительно,
будет либо открываться окно Form2 (если использовать Form2.Show),
либо окно будет загружено в память, но не будет отображаться (если испльзовать Load Form2)
что в обоих случаях не очень хорошо.

Такая кнопка может быть необходима для изменения списков комбобоксов открытых окон Form2
то есть при добавлении в список List1 нужно добавить во все списки Form2.Combo1
Но даже здесь можно обойтись без такой кнопки, а автоматически добавлять строку во все списки:
Form1.List1.AddItem "NewLine"
For Each F In Forms
if F.Name = "Form2" then
F.Combo1.AddItem "NewLine"
End If​
Next F
 
A

Alex77777

Гость
#5
я что-то совсем не могу здесь разобраться
я не умею работать с модулями, пытался применять их в работе, но ничего неполучается.
объявляю
Public Function CopyListToCombo(source As ListBox, target As ComboBox) As Long в Form1
а в Form_Load формы Form2 пишу
Dim success As String
success = Form1.CopyListToCombo
Combo1.AddItem success

он ругается Ошибка компиляции: Argument not optional

пробовал и так в Form_Load формы Form2

Dim success As Long
Function CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End Function

пишет Expected End Sub
 
T

Tanya

Гость
#6
По второму варианту :
обрати внимание на то что Form_Load это Sub, а не Function
поэтому и пишет Expected End Sub

Код:
Dim success As Long
Function CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End Sub
 
A

Alex77777

Гость
#7
я понимаю что пытаюсь в процедуру Form_Load запихнуть функцию. только вот никак не получается.
не могу понять как здесь быть. :blink:
 
T

Tanya

Гость
#8
эта функция может быть вынесена в отдельный модуль и объявлена
как глобальная (то есть возможно она может быть объявлена глобальной
и в модуле формы, наверно ..., я не уверена :))

Function CopyListToCombo(List1, Combo1)
If success Then Combo1.ListIndex = 0
End function

а затем вызвана из модуля формы (любой формы)
например

Private Sub Form_Load()
Dim success As String
success = CopyListToCombo(Form1.List1, Form2.Combo1)
Form2.Combo1.AddItem success
End Sub