Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Excel VBA

Модерирует : ShIvADeSt

ShIvADeSt (23-04-2007 01:59): http://forum.ru-board.com/topic.cgi?forum=33&topic=8273  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

   

RUSmafia



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

 
 
Обсуждаем вопросы только по Excel VBA
(программирование макросов, скриптов, пользовательских функций и т.п.).
Приветствуются ссылки на ресурсы и справочную литературу по теме.
 
Вопросы по работе с MS Excel, не относящиеся к программированию, задаем в теме Excel FAQ

 
Обратите внимание, этот топик для помощи в изучении и использовании VBA. Посему запросы типа "Напишите мне такой-то макрос, я VBA не знаю и знать не хочу" не приветствуются.
Древняя мудрость: "Накорми голодного рыбой и он погибнет, научи его ловить рыбу и ты спасешь его."(R)
 
Информация общего характера:
  • Список соответствия имен функций в английской и русской версиях Excel
  • Описание Microsoft Excel File Format
     
    Рекомендации:
    Если у Вас есть проблема, не решаемая стандартными средствами Excel (об этом можно уточнить здесь) или требующая автоматизации, попробуйте для начала записать макрос самим Excel через меню Сервис (Tools) - Макрос (Macro) - Начать запись (Record New Macro). Подробнее здесь. В большинстве случаев получившийся код (Сервис-Макрос-Макросы-Изменить) Вас не удовлетворит, но подскажет, какие объекты-методы-свойства использовать.  
    Другой Ваш помощник - Просмотр объектов (Object Browser). Ну и встроення помощь (F1), естественно.
     
    Если Вы в тупике, покажите Ваш код (или часть кода) здесь.  Если вылазит ошибка, цитируйте ее полностью. Если код слишком большой, используйте тeг [more].
    Используйте отладчик - Breakpoints (F9), Watches (Shift-F9), Steps (F8 и др.) Сильно облегчает поиск ошибок.

     
    Рекомендуется к прочтению:
  • Первые шаги с Excel VBA
  • Excel VBA: Приёмы программирования
  • WinApi. Лекция из курса "Основы офисного программирования и язык VBA" (для продвинутых)
  • Daily Dose of Excel (eng.) - тематический блог: советы по работе с Excel и прочие материалы
  • Excel Macros & Excel VBA Code Tips, Tricks (eng.) - советы, трюки и уловки
  • Mr. Excel (forum) (eng.) - весьма оживленный форум по Excel&VBA.
     
    Родственные топики:
  • Вопросы по работе с MS Excel - Excel FAQ - часть 1, часть 2
  • Технические проблемы с MS Office 2003 или Office XP.
  • Word VBA все вопросы по Word VBA туда
  • Access все вопросы по программированию в Access туда
  • Книжульки по VBA - книги по программированию с использованием VBA
     
    Конкретные вопросы:
    Форма-заставка
    Как запустить макрос при изменении положения курсора или значения ячейки
  • Пример 1
  • Пример 2
  • Пример 3 (проверка области)
  • Пример 4
  • Пример 5
    Зацикливание в функции Change или SelectionChange
     
    Ранжирование без пробелов (макрос включает функции сортировки массива и удаления дубликатов, работает и в Excel 2007)
  • под Office 97
     
    Добавление в главное меню своего пункта, ассоциированного с макросом
    Создание ярлыка на рабочем столе
    Снятие защиты листа при забытом пароле
    Смена раскладки клавиатуры
    Скролл формы колесом прокрутки мыши
    Оптимизация кода по быстродействию использованием массивов

  • Всего записей: 556 | Зарегистр. 31-07-2002 | Отправлено: 21:40 14-10-2004 | Исправлено: lucky_Luk, 20:44 13-04-2007
    ZORRO2005



    Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    The okk

    Цитата:
    А для чего столбец D?

    Да в столбце D уникальные значения столбца F.
    В столбце F будет около 1500 строк и примерно 1000 уникальных значений.
    Это я названия месяцев для примера поставил.
    Вообще в столбце F будут артикулы одежды,
    а напротив каждого артикула в столбце G цвета.
     
     

    Всего записей: 342 | Зарегистр. 08-10-2005 | Отправлено: 16:58 09-01-2007
    alin



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Имеется рабочий лист, который формируется на каждый день путем копирования старого листа и удаления из таблиц данных (кроме формул). На листе имеются ToggleButton*, которые вставляют формулы в ячейки (по необходимости). Как сделать, чтобы при формировании нового листа эти кнопки имели вид ToggleButton*.Value = False?

    Это возможно реализовать?

    Всего записей: 683 | Зарегистр. 05-08-2004 | Отправлено: 21:16 09-01-2007
    Yuk



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    alin

    Цитата:
    Как сделать, чтобы при формировании нового листа эти кнопки имели вид ToggleButton*.Value = False?

    Как происходит формированиеие нового листа? Через VBA макрос?
    Тогда в этом же макросе в цикле проходишь по всем ToggleButton на листе и присваиваешь им значение False.
     
     
    Добавлено:
    Реализация:

    Код:
    For Each s In Worksheets(1).Shapes
        If s.Type = msoOLEControlObject Then
            If InStr(s.OLEFormat.progID, "ToggleButton") > 0 Then
                s.OLEFormat.Object.Object.Value = False
            End If
        End If
    Next

    Всего записей: 1182 | Зарегистр. 02-07-2001 | Отправлено: 22:01 09-01-2007
    alin



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Yuk

    Цитата:
    Как происходит формированиеие нового листа? Через VBA макрос?  
    Да

    Цитата:
    For Each s In Worksheets(1).Shapes  
        If s.Type = msoOLEControlObject Then  
            If InStr(s.OLEFormat.progID, "ToggleButton") > 0 Then  
                s.OLEFormat.Object.Object.Value = False  
            End If  
        End If  
    Next  

    Поясни, пожалуйста, все кнопки ToggleButton1, ToggleButton2, ToggleButton* будут иметь положение False? В моём случае ToggleButton1…*.Value = False заносят формулы, ToggleButton1…*.Value = True - формулы удаляются. Желательно, чтобы на новом листе формулы были удалены.

    Всего записей: 683 | Зарегистр. 05-08-2004 | Отправлено: 00:30 10-01-2007 | Исправлено: alin, 00:31 10-01-2007
    Yuk



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    alin
    Если Application.EnableEvents = True, по идее должно отработать событие, привязанное к изменению статуса ToggleButton. В принципе, формулы можно удалить и программным путем из того же макроса, тем более код у тебя уже есть. Короче, тестируй.

    Всего записей: 1182 | Зарегистр. 02-07-2001 | Отправлено: 00:41 10-01-2007
    alin



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Yuk
    Спасибо, буду пробовать.

    Всего записей: 683 | Зарегистр. 05-08-2004 | Отправлено: 01:16 10-01-2007
    aks_sv

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Кто-нибудь подскажет, как решить такую задачку: имеется ListBox с девятью колонками, из них отображается только одна, остальные ColumnWidths 0 pt. Как при помощи нажатия, например, кнопки ОК на форме, переместить все 9 колонок c ListBox в таблицу.  
    Для пояснения:  
    ListBox заполняется из этой же таблицы с 9 колонками, затем на форме сортируется произвольным образом, необходимо чтобы в  ListBox отображалась только одна колонка.

    Всего записей: 109 | Зарегистр. 18-12-2006 | Отправлено: 05:54 10-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    aks_sv

    Код:
     
    Application.ScreenUpdating = False
    With Worksheets(номер_листа)
    .Range(.Cells(первая_строка,первый столбец), _
    .Cells(последняя_строка,послений_столбец)) = _
    Me.ListBox1.List
    End With
    Application.ScreenUpdating = True

     
    Где:
    номер_листа - номер листа (или его название в кавычках), куда ты будешь выгружать данные из ListBox.
    первая_строка,первый столбец - координаты верхней левой ячейки диапазона на этом листе, куда будет выгружен ListBox.
    последняя_строка,послений_столбец - координаты нижней правой ячейки диапазона на этом листе, куда будет выгружен ListBox.
     
    Если координаты диапазона постоянные (например, A1:D3) и никогда не меняются (т.е. количество строк и столбцов не меняется), то вместо:

    Код:
    .Range(.Cells(первая_строка,первый столбец), _
    .Cells(последняя_строка,послений_столбец))

    Можно сразу подставить координаты диапазона. Например:

    Код:
    .Range("A1:D3")

     
    В общем, все также, как при загрузке, только левая и правая часть равенства меняются местами. Ты же как-то загрузил данные в форму . Если я непонятно объясняю, могу пример выложить.
     
    ZORRO2005
    Столбец "F" отсортирован? Т.е. может ли возникнуть ситуация, когда после:
    Декабрь
    Декабрь
    Декабрь
    Март

    могут встретиться еще записи с декабрем?
    И если такая ситуация возможна, допустима ли сортировка по столбцу "F"?

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 08:13 10-01-2007 | Исправлено: The okk, 09:05 10-01-2007
    ZORRO2005



    Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    The okk

    Цитата:
    Столбец "F" отсортирован?

    Я могу его предварительно отсортировать

    Всего записей: 342 | Зарегистр. 08-10-2005 | Отправлено: 09:29 10-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ZORRO2005
    Не стОит - сортировку и в макросе сделать можно .

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 09:40 10-01-2007
    aks_sv

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    The okk

    Цитата:
    Application.ScreenUpdating = False  
    With Worksheets(номер_листа)  
    .Range(.Cells(первая_строка,первый столбец), _  
    .Cells(последняя_строка,послений_столбец)) = _  
    Me.ListBox1.List  
    End With  
    Application.ScreenUpdating = True  

     
    Сделал как ты сказал, все-равно снимает с ListBox_а один столбец в таблицу

    Всего записей: 109 | Зарегистр. 18-12-2006 | Отправлено: 10:10 10-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    aks_sv
    Если бы ты сделал, как я сказал, выгружались бы все данные  целиком (я проверял )
    Тут несколько вариантов - либо у тебя в ListBox столбец только один, либо ты задал диапазон из одного столбца (первый_столбец = последний_столбец).
    Выложи свой файл - тогда смогу сказать точно.

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 10:53 10-01-2007 | Исправлено: The okk, 11:11 10-01-2007
    aks_sv

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    The okk
    [q][/q]
    Private Sub UserForm_Initialize()
        Application.ScreenUpdating = False
        ListBox1.ColumnCount = 9
        ListBox1.ColumnWidths = "30;0;0;0;0;0;0;0;0"
        Dim myArray As Variant
        myArray = Worksheets("Данные").Range("A2:I400")
        ListBox1.List = myArray
    End Sub
     
    Действительно, у меня загружается один стобец, почему?
     
     
    Добавлено:
    The okk
    Private Sub cb_EmpExit_Click()
        Application.ScreenUpdating = False
        Dim LastRow As Long
        LastRow = Range("A65536").End(xlUp).Row
            With Worksheets("Список")
            .Range(.Cells(2, 1), _
            .Cells(LastRow, 9)) = _
            Me.ListBox1.List
            End With
        Unload Me
        Worksheets("Табель").Activate
    End Sub
     
    А как вы пишите мелким шрифтом на белом фоне в форуме?
     
    Добавлено:
    The okk
    Получается, что все ж загружаютя, потому, что еслизаписать:
    ListBox1.ColumnWidths = "30;30;0;0;0;0;0;0;0"
    то все ОК, только в окне два столбца, а мне не надо
     
    Добавлено:
     
    Нет все нормально, только когда я начинаю значения в Listbox перемещать вверх-вниз, тогда не получается
     
    Private Sub Up_Button_Click()
        If ListBox1.ListIndex <= 1 Then Exit Sub
        NumItems = ListBox1.ListCount
        Dim TempList()
        ReDim TempList(0 To NumItems - 1)
    '   Заполнить массив опциями списка
        For i = 0 To NumItems - 1
            TempList(i) = ListBox1.List(i)
        Next i
    '   Выделенные пункты
        ItemNum = ListBox1.ListIndex
    '   Обменять элементы
        TempItem = TempList(ItemNum)
        TempList(ItemNum) = TempList(ItemNum - 1)
        TempList(ItemNum - 1) = TempItem
        ListBox1.List = TempList
    '   Изменить индекс списка
        ListBox1.ListIndex = ItemNum - 1
    End Sub
    Private Sub Down_Button_Click()
        If ListBox1.ListIndex = ListBox1.ListCount - 1 Then Exit Sub
        NumItems = ListBox1.ListCount
        Dim TempList()
        ReDim TempList(0 To NumItems - 1)
    '   Заполнить массив опциями списка
        For i = 0 To NumItems - 1
            TempList(i) = ListBox1.List(i)
        Next i
    '   Выделенные пункты
        ItemNum = ListBox1.ListIndex
    '   Обменять элементы
        TempItem = TempList(ItemNum)
        TempList(ItemNum) = TempList(ItemNum + 1)
        TempList(ItemNum + 1) = TempItem
        ListBox1.List = TempList
    '   Изменить индекс списка
        ListBox1.ListIndex = ItemNum + 1
     
    End Sub

    Всего записей: 109 | Зарегистр. 18-12-2006 | Отправлено: 11:46 10-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    А как вы пишите мелким шрифтом на белом фоне в форуме?

    Используй форумные теги в сообщениях.
     
    Можешь сам посмотреть, что твой код делает - добавь в код точки останова (F9) и запусти. А в ходе выполнения кода открой окно Watches и перетащи туда Me.ListBox1.List и увидишь со всеми подробностями, что происходит с элементами. - В будущем тебе еще не раз пригодится это окошко.
    P.S.:Не люблю я Debug.print - жутко неудобно.
     

    Цитата:
    Private Sub Up_Button_Click()  
        If ListBox1.ListIndex <= 1 Then Exit Sub  
        NumItems = ListBox1.ListCount  
        Dim TempList()  
        ReDim TempList(0 To NumItems - 1)  
    '   Заполнить массив опциями списка  
        For i = 0 To NumItems - 1  
            TempList(i) = ListBox1.List(i)  
        Next i  
    '   Выделенные пункты  
        ItemNum = ListBox1.ListIndex  
    '   Обменять элементы  
        TempItem = TempList(ItemNum)  
        TempList(ItemNum) = TempList(ItemNum - 1)  
        TempList(ItemNum - 1) = TempItem  
        ListBox1.List = TempList  
    '   Изменить индекс списка  
        ListBox1.ListIndex = ItemNum - 1  
    End Sub  

    "меня терзают смутные сомненья..." ©
    А работает ли вообще этот код? Где Else, End If? Да и переменные NumItems и ItemNum хорошо бы объявить - это не так критично, как отсутствие End If, но все же между Variant и Long разница есть.
    Насколько я понял, одна кнопка должна перемещать выделенный элемент вверх, а другая - вниз. А вот алгоритм перемещения не могу разобрать. как это должно работать?

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 12:39 10-01-2007 | Исправлено: The okk, 12:56 10-01-2007
    aks_sv

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    The okk

    Цитата:
    Спасибо за теги и про отладку

    А насчет работы кода не сомневайся, работает прекрасно я в какой-то книжке вычитал давно

    Всего записей: 109 | Зарегистр. 18-12-2006 | Отправлено: 12:56 10-01-2007 | Исправлено: aks_sv, 12:59 10-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    aks_sv
    честно говоря, сомневаюсь, что в этой книжке был код для твоего случая. Поскольку предназначен этот код для случая ListBox с одним столбцом.  
     
    Ты в алгоритме разберись:
     
    ЕСЛИ выделен не первый и не второй элемент, ТО
    1. Скопировать весь первый столбец во временный массив (TempList). В результате имеем одномерный массив.
    2. Переставить в этом массиве элементы через буфер
    3. Загрузить этот ОДНОМЕРНЫЙ массив в ListBox.
     
    Вот так при нажатии кнопки у тебя остается только первый столбец.
     
    Если уж все копировать в массив, то копировать целиком в двойном цикле - вместо List(i) - List(i,j), где j меняется от 0 до 8 (поскольку столбцов 9).
    И менять местами тоже все эти подэлементы. Вот так выглядит исправленный код
    Вставь вместо своего и исправь код второй кнопки по этому образцу.
     
    Но я бы наверное сделал проще - копируем в буфер только сам элемент (с подэлементами), удаляем его (через RemoveItem), добавляем элемент в нужную позицию (AddItem). И уже в добавленный элемент записываем из буфера данные. И не надо дважды переписывать весь массив. По крайней мере, в свое время в ListView я делал именно так.
     


    Буржуи куражились на тему "Как перенести массив на лист в VBA".
    Вообще, интересный сайт. Там и Джон Уокенбах появляется.

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 13:38 10-01-2007 | Исправлено: The okk, 15:02 10-01-2007
    Anton T

    Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Кому-то надо группировки одинаковых имен и т.д.?
    Вставь новая форма, добавь элемент поля со списком и вставить туда коды:

    Код:
    Function ГруппаТекст(ByVal ARange As Range) As String()
        Dim Cnt As Long, i As Long, TArr(), TArrItm, TempArr() As String
        Dim tArea As Range
        ReDim TempArr(0)
        For Each tArea In ARange.Areas
            TArr = tArea.Value
            For Each TArrItm In TArr
                If Len(TArrItm) > 0 Then
                    For i = 0 To Cnt - 1
                        If TempArr(i) = TArrItm Then Exit For
                    Next
                    If i = Cnt Then
                        ReDim Preserve TempArr(Cnt)
                        TempArr(Cnt) = TArrItm
                        Cnt = Cnt + 1
                    End If
                End If
            Next
        Next
        ГруппаТекст = TempArr
    End Function
     
    Private Sub UserForm_Initialize()
        ComboBox1.List = ГруппаТекст(Range("a1:a10"))
    End Sub
     

    Ну думаешь я крутой... ))))
     
    Добавлено:
    Пример, в столбце А:
    Александр
    Александр
    Сергей
    Максим
    Сергей
     
    а в поля со списком будет отображена:
    Александр
    Сергей
    Максим
     

    Всего записей: 325 | Зарегистр. 12-04-2006 | Отправлено: 15:11 10-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Anton T
    Лучше все же писать комментарии к коду или алгоритм
    Кстати, столбец с уникальными значениями делается формулой .

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 15:30 10-01-2007
    aks_sv

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    The okk
    Спасибо все отлично работает
    Цитата:
    Если уж все копировать в массив, то копировать целиком в двойном цикле - вместо List(i) - List(i,j), где j меняется от 0 до 8 (поскольку столбцов 9).  
    И менять местами тоже все эти подэлементы. Вот так выглядит исправленный код  
    Вставь вместо своего и исправь код второй кнопки по этому образцу.  

    Спасибо все отлично работает

    Всего записей: 109 | Зарегистр. 18-12-2006 | Отправлено: 16:09 10-01-2007
    Yuk



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ZORRO2005
    В код листа:
    Код:
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim frm As String
    frm = ""
    If Target.Address = "$A$2" Then
        For Each c In Range(Range("F1"), Range("F1").End(xlDown)).Cells
            If c.Value = Target.Value Then
               frm = frm & "," & c.Offset(0, 1).Text
            End If
        Next
        With Range("B2").Validation
            .Delete
            .Add Type:=xlValidateList, Formula1:=frm
            .IgnoreBlank = True
            .InCellDropdown = True
            .ShowInput = True
            .ShowError = False
        End With
    End If
    End Sub

     
    Добавлено:
    Сортировать не обязательно.

    Всего записей: 1182 | Зарегистр. 02-07-2001 | Отправлено: 17:56 10-01-2007
       

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Excel VBA
    ShIvADeSt (23-04-2007 01:59): http://forum.ru-board.com/topic.cgi?forum=33&topic=8273


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru