Специалистам и знатокам по VBA: HELP!

Компьютеры, программы, периферия, коммуникации, интернет, программирование и т.п. Ранее назывался Hard-n-Soft.
Сообщение
Автор
Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 0 Сообщение Splinter » 06 сен 2006 20:43

Сорри за такое ламерство, но я совершенно не помню, как обрабатывается элемент combobox.

Нужно сделать combobox, содержащий определенное число пунктов. По факту выбора того или иного пункта переменной присваивается определенное значение. Вба-шных хелпов под руками нет. :(

Нужно срочно. Завтра к обеду тема будет уже неактуальна.

rook
Благодарил (а): 6 раз
Поблагодарили: 4 раза

№ 1 Сообщение rook » 06 сен 2006 21:31

Есть событие изменения комбобокса:
Private Sub ComboBox1_Change()
И переменная, которая хранит в себе номер выбранного в данный момент пункта (отсчет с 0):
A = ComboBox1.ListIndex + 1
End Sub
То есть в А всегда будет лежать номер выбранного сейчас пункта

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 2 Сообщение Splinter » 06 сен 2006 21:46

1: rook
А как заполнить-то комбобокс нужными вариантами (при инициализации формы)?

TheJudge
Аватара пользователя
SVGA
Благодарил (а): 268 раз
Поблагодарили: 853 раза

№ 3 Сообщение TheJudge » 06 сен 2006 21:58

2: Splinter

combobox1.AddItem


вообще, если есть Excel например, жми alt+f11, создавай проект и там экспериментируй, он тебе даже подпишет

типа пишешь combobox1, ставишь точку и он тебе варианты продолжения

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 4 Сообщение Splinter » 06 сен 2006 22:14

3: TheJudge

Код: Выделить всё

Private Sub ComboBox1_Change()
ComboBox1.AddItem = "test1"
ComboBox1.AddItem = "test2"
End Sub
Выдает пустой комобокс без вариантов.

rook
Благодарил (а): 6 раз
Поблагодарили: 4 раза

№ 5 Сообщение rook » 06 сен 2006 22:21

Если просто нужно тупо и навсегда ввести в него текст то
Private Sub UserForm_Initialize()
ComboBox1.AddItem 1
ComboBox1.AddItem "aaaa"
ComboBox1.AddItem 3
End Sub
и т.д

из экселевской таблицы можно так:

Private Sub UserForm_Initialize()
For i = 1 To get_record_count(1)
ComboBox1.AddItem Sheets("sheet1").Cells(i, 1).Value
Next i
End Sub

Public Function get_record_count(par As Integer) As Integer
Dim record_count As Integer
record_count = 1
Do While Trim(Sheets("sheet1").Cells(record_count, par).Value) <> ""
record_count = record_count + 1
Loop
get_record_count = record_count - 1
End Function

sheet1 - название листа
par - номер столбца из которого надо данные взять.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 6 Сообщение Splinter » 06 сен 2006 22:37

Все, понял.

Код: Выделить всё

Private Sub UserForm_Initialize()
Label1.Caption = "Режим не определен"
ComboBox1.AddItem "Mode1"
ComboBox1.AddItem "Mode2"
ComboBox1.AddItem "Mode3"
ComboBox1.AddItem "Mode4"
ComboBox1.AddItem "Mode5"
ComboBox1.AddItem "Mode6"
End Sub

Код: Выделить всё

Private Sub ComboBox1_Change()
Dim Mode As Integer
Mode = ComboBox1.ListIndex
Select Case Mode
Case 0
Label1.Caption = "Заполнение"
Case 1
Label1.Caption = "Опустошение"
Case 2
Label1.Caption = "Хранение"
Case 3
Label1.Caption = "Авария"
Case 4
Label1.Caption = "Ремонт"
Case 5
Label1.Caption = "Буферизация"
End Select
End Sub
Работает как надо, дальше справлюсь сам.
Спасибо, выручили.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 7 Сообщение Splinter » 27 сен 2006 17:01

Задача номер два.

На форме имеются элементы DriveListBox, DirListBox и FilListBox для навигации по компьютеру и выбора нужного файла.

По клику по DriveListBox'у в заголовке Label1 указывается количество папок в корне диска.

Код: Выделить всё

Label1.Caption = Dir1.ListCount
Дальше я в скрипте присваиваю свойству ListIndex элемента DirListBox значение, к примеру 9. Т.е. указываю на восьмую папку в списке папок выбранного диска.

Каким образом я могу получить имя этой папки в строковую переменную?

TheJudge
Аватара пользователя
SVGA
Благодарил (а): 268 раз
Поблагодарили: 853 раза

№ 8 Сообщение TheJudge » 27 сен 2006 22:59

хм... полистал книжку, не нашёл штатных средств

ИМХО, наиболее правильным будет, при выборе папки забивать строковое значение не только в caption, но и в дополнительную переменную

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 9 Сообщение Splinter » 28 сен 2006 16:23

8: TheJudge
Блин.

И еще вопрос. Как узнать размер папки? По аналогии с FileLen для получения размера файла.
В хелпах ничего подобного не нашел.

rook
Благодарил (а): 6 раз
Поблагодарили: 4 раза

№ 10 Сообщение rook » 28 сен 2006 19:34

Splinter :
> 8: TheJudge
> Блин.
>
> И еще вопрос. Как узнать размер папки? По аналогии с FileLen для получения
> размера файла.
> В хелпах ничего подобного не нашел.

Однозначно можно только вручную складывать размер файлов, содержащихся в папке :(
По другому никак...

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 11 Сообщение Splinter » 22 окт 2006 09:14

Вопрос посложнее.

Есть mdb'шная база данных. Есть форма, созданная средствами VBA, на которой отображаются значения, содержащиеся в БД.

На форме два контрола: ADO Data Control и DataRepeater Control. У ADODC значение свойства ConnectionString слежующее:

Код: Выделить всё

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Personal\VB_Projects\UEFA\UEFA.mdb;Persist Security Info=False
Это, понятное дело, строка подключения к БД. Дальше свойством RecourdSource я делаю выборку из БД, записывая в него (свойство) следующее значение, прежставляющее собой SQL-запрос:

Код: Выделить всё

select * from teams where points=6
Все вроде бы работает, при запуске на форме отображаются только те записи БД, которые удовлетворяют запросу из RecordSource.
Но проблема в том, что мне не нужна жесткая привязка к запросу. Нужно, чтобы он менялся в зависимости от требований пользователя.

Если я вношу в код (событие Form_Load) следующую строку:

Код: Выделить всё

Adodc1.RecordSource = "select * from teams where points=9"
то все равно выполняется запрос из RecordSource'а (т.е. "points=6").
Почему игнорируется второй запрос?
Как сделать так, чтобы выполнялся запрос, указанный в коде?

rook
Благодарил (а): 6 раз
Поблагодарили: 4 раза

№ 12 Сообщение rook » 22 окт 2006 10:39

Splinter :
Может заработает, если рефреш добавить?:
Adodc1.RecordSource = "select * from teams where points=9"
Adodc1.Refresh

deniska
Благодарил (а): 2 раза

№ 13 Сообщение deniska » 24 окт 2006 14:02

С базой данных Аксесс (MDB) лучше и быстрее работать через DAO.
ADO конечно более универсален, но в данном конкретном случае через DAO будет и проще и быстрее. Imho

Паша_с_Уралмаша
Аватара пользователя
Поблагодарили: 3 раза

№ 14 Сообщение Паша_с_Уралмаша » 02 ноя 2006 18:02

13: deniska
согласен. кроме того, апдейт таблицы при этом можно ручками описать, а не и5аццо извините с движком.
а саму таблицу отображать в форме через ListView в режиме таблицы.
Рукопашной тут много. Зато понятней и борьба с дураком-оператором описывается нагляднее.
имхо опятьже.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 15 Сообщение Splinter » 12 дек 2006 12:56

Каким образом проверить валидность урла?

Т.е. есть стринговая переменная, к примеру, adressURL, в которую передается та абракадабра, которую оператор ввел в Text1.Text.

Как узнать, существует ли страничка в инете с подобным адресом?

BadBlock
Аватара пользователя
Благодарил (а): 1586 раз
Поблагодарили: 8126 раз

№ 16 Сообщение BadBlock » 12 дек 2006 13:13

> Как узнать, существует ли страничка в инете с подобным адресом?

Не знаю, как там у вас на VBA, а у нас для этого обычно открывают сокет на 80 порт на указанный хост, производят HTTP-запрос указанного URI и анализируют код ответа, с проверками на каждом этапе.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 17 Сообщение Splinter » 14 ноя 2012 17:50

Хых, обновим тему.

Что дано.
На форме множество элементов Label, объединенных в массив Label1(N).
Пусть N равно сотне, условно говоря.

Присваивать им свойство caption - нет проблем, все в цикле делается на раз.

Но есть нюанс.
По клику на конкретный элемент массива Label1(N) нужно менять его (конкретного элемента, а не всего массива) свойство. Например, цвет.

Т.е. пользователь кликнул на Label1(48) - этот элемент на форме стал красного цвета.

В VBA есть событие Click, конечно, но вот в цикл его не засунуть.
Неужели для каждого элемента массива из ста элементов копипастить код?

old
Поблагодарили: 8 раз

№ 18 Сообщение old » 14 ноя 2012 19:19

Ну кроме твоего массива - там вроде есть коллекция controls. Если в эту сторону копнуть - давное не писал именно на VB, но помнится именно так универс. делалось

Паша_с_Уралмаша
Аватара пользователя
Поблагодарили: 3 раза

№ 19 Сообщение Паша_с_Уралмаша » 14 ноя 2012 21:09

а я сдулся.. ппц.. них не помню

TheJudge
Аватара пользователя
SVGA
Благодарил (а): 268 раз
Поблагодарили: 853 раза

№ 20 Сообщение TheJudge » 14 ноя 2012 21:14

17: Splinter:

А нет событий более глобальных? Т.е. типо клик в пределах формы и дальше проверка в цикле, не кликнули ли кого из твоих Label? Хотя с точки зрения скорости обработки, лучше привязать код к каждому Label. Сам уже давно не кодал на VBA, но подобную задачу когда-то решал. Не помню, правда, уже, как. Надо будет поискать исходники на досуге.

old
Поблагодарили: 8 раз

№ 21 Сообщение old » 14 ноя 2012 22:18

по простому походу не получится. В принципе для динамически создаваемых контролов (в цикле например) можно повесить одно событие по клику и уже в нем все описывать.

для кнопок примерно так

Код: Выделить всё

Public WithEvents MyCB As VB.CommandButton

Private Sub MyCB_Click()
MsgBox "Я тута!"
End Sub
в саммом событии можно уже навернуть и проверять в каком контроле оно произошло

Код: Выделить всё

Dim cl1 As New Class1

Private Sub UserForm_Initialize()
Set cl1.MyCB = Form1.Controls.Add("VB.CommandButton", "Control" & Form1.Controls.Count)
With cl1.MyCB
    .Left = 0 'Расположение слева
    .Top = 50 'Расположение сверху
    .Width = 290 'Ширина
    .Height = 30 'Длина
    .Visible = True 'Сделать объект видным
    .Caption = "Я кнопка" 'Текст на кнопке
End With
End Sub
А уже в вытащенных на форму кроме как прописывания в каждом походу не выйдет.

Пойманый_маньяк
Аватара пользователя
Благодарил (а): 404 раза
Поблагодарили: 694 раза

№ 22 Сообщение Пойманый_маньяк » 15 ноя 2012 01:40

По идее в ООП в таких случаях (конкретно про VBA не знаю, но на Delphi и на C - именно так и писал) делается общая функция, по клику на любом из Label. Из входного параметра этой общей функции (в Delphi ЕМНИП это был Sender) вычисляется - какой именно Label кликнули.
И дальше делаешь конкретно с ним что хочешь. Хоть видимость меняешь, хоть цвет, хоть текст.

Пойманый_маньяк
Аватара пользователя
Благодарил (а): 404 раза
Поблагодарили: 694 раза

№ 23 Сообщение Пойманый_маньяк » 15 ноя 2012 01:45

В крайне общих чертах (под рукой ничего из этой серии :) ).

procedure AllLabelsOnClick(sender);
begin
sender.color := #АА;
end;

Пойманый_маньяк
Аватара пользователя
Благодарил (а): 404 раза
Поблагодарили: 694 раза

№ 24 Сообщение Пойманый_маньяк » 15 ноя 2012 02:25

Тьфу блин. Боюсь ввел в заблуждение.
В VB.Net появилось возможность создовать несколько процедур для одного объекта реагирующих на одно событие(например, Click), или наоборот, одну процедуру реагирующию на события для нескольких объектов.

Код: Выделить всё

Private Sub Новое_Событие(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click 
' Событие реагирует на нажатие 3ех кнопок
MsgBox("Событие для 3ех кнопок")
End Sub
http://vbbook.ru/vb.net/procedyru-v-vbnet/
Это уже в Vb.Net. Там такое вполне бы прокатило.
Извиняюсь.

Пойманый_маньяк
Аватара пользователя
Благодарил (а): 404 раза
Поблагодарили: 694 раза

№ 25 Сообщение Пойманый_маньяк » 15 ноя 2012 02:55

А вообще можно подумать о переходе на Visual Studio например.
И работать с Excel из нее.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 26 Сообщение Splinter » 04 дек 2014 01:29

А вот некроап.

Вопрос не совсем про VBA, скорее просто про Excel.
Не хочется скрипты городить, может как формулами и функциями можно обойтись.

Есть массив.

Код: Выделить всё

               Сотрудник 1           Сотрудник 2          Сотрудник 3           Сотрудник 4          Сотрудник 5
День 1             5                     2                    4                     6                    1
День 2             1                     3                    2                     1                    3
День 3             2                     7                    1                     6                    2
День 4             5                     5                    5                     3                    4
День 5             1                     0                    2                     4                    7
ВСЕГО             14                    17                   14                    20                   17
Понятно, что в графу ВСЕГО вставлена функция СУММ().
Теперь необходимо в отдельные ячейки выписать сотрудников с минимальным и максимальным значениями из строки ВСЕГО.

Есть функции МИН() и МАКС(), но они выдадут именно значения, числа.
А вот как сделать бы, чтобы выдавались именно фамилии сотрудников (Сотрудник 1, Сотрудник 2, ...)?
Т.е. найти максимальное значение (ага, вот 20 максимальное), а в ячейку вывести уже не число 20, а "Сотрудник 4".

TheJudge
Аватара пользователя
SVGA
Благодарил (а): 268 раз
Поблагодарили: 853 раза

№ 27 Сообщение TheJudge » 04 дек 2014 11:58

26: Splinter:

Это будет убервложенная функция. Проще скрипт написать.

А то ищешь максимальное значение, а потом функциями возвращаешь адреса столбцов, где она есть, и оттуда уже можно взять будет сотрудника. Но если значений больше 1, то уже ой. Разумнее скрипт.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 28 Сообщение Splinter » 04 дек 2014 12:03

27: TheJudge:
> Но если значений больше 1, то уже ой.

Массив 15 на 8: пятнадцать столбцов по восемь значений в каждом.
Причем не факт, что максимальные и минимальные значения будут в единственном числе: может быть два равных максимальных, например.

Я пробовал городить всё это через мега-вложенность (ЕСЛИ(ЕСЛИ(ЕСЛИ(ЕСЛИ...)))), на пятом или шестом вложении запутался в синтаксисе и плюнул.

Видимо, действительно, скриптом напишу.

Splinter
Аватара пользователя
Не грузин
Благодарил (а): 91 раз
Поблагодарили: 487 раз

№ 29 Сообщение Splinter » 04 дек 2014 12:18

Ан нет, нашел функцию ГПР(), но пока не понял как она работает и как её приспособить.
Но, судя по описанию, что-то похожее на то, что надо.
Выполняет поиск значения в первой строке таблицы или массива значений и возвращает значение, находящееся в том же столбце в заданной строке таблицы или массива.

Вернуться в «Компьютерный форум»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей