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

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в 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
    Pantera3587

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

    Цитата:
    Наверное, вот так...  

    Спасибо, что откликнулся на мой вопрос, но этот код почему-то не заработал, пишет, что не определен (выделяет желтым цветом) следующую строку
        Worksheets("Лист2").Range(Cells(1, 1), _  
        Cells(lRowsCount, lColCount)) = .UsedRange  
    А вот код Anton T заработал. Большое спасибо.

    Всего записей: 40 | Зарегистр. 20-10-2006 | Отправлено: 15:10 16-01-2007
    Troitsky



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

    Цитата:
    для чекбокса надо еще иметь и значок без галки

    ну так ручки же есть - самому нарисовать и через свойство Picture прицепить. можно и маску использовать (свойство Mask).
    Как сделаешь - выложи код.
     
    Если кто знает другой способ - пишите.


    ----------
    Мы в хорошем настроении гуляем по лесам.
    Кто обидеть нас захочет – сам получит по усам.
    Сам полу- получит по усам. Сам полу- получит по усам!

    Всего записей: 795 | Зарегистр. 13-12-2003 | Отправлено: 17:11 16-01-2007
    Yuk



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

    Цитата:
    для двух строк подобрать наиболее подробный шаблон/маску

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

    Всего записей: 1182 | Зарегистр. 02-07-2001 | Отправлено: 19:54 16-01-2007
    crewgehr

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    to SERGE_BLIZNUK & The okk
     
    Большое спасибо - всё работает.
     
    Отдельное спасибо SERGE_BLIZNUK за весьма познавательную ссылку.
     

    Всего записей: 6 | Зарегистр. 19-12-2006 | Отправлено: 00:30 17-01-2007
    ShIvADeSt



    Moderator
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    есть лист на котором очень часто встречается примерно такая формула

    Код:
     
    ='C:\Temp\[Финдонесение январь 2007 г.1.xls]15'!$F$9-'C:\Temp\[Финдонесение январь 2007 г.1.xls]15'!$G$9-'C:\Temp\[Финдонесение январь 2007 г.1.xls]15'!$H$9-'C:\Temp\[Финдонесение январь 2007 г.1.xls]15'!$K$9+'C:\Temp\[Финдонесение январь 2007 г.1.xls]15'!$Q$9
     

    этот лист также имеет имя 15, как и соотв лист с другой книги. Как сделать, чтобы при копировании этого листа на имя 16 в формуле C:\Temp\[Финдонесение январь 2007 г.1.xls]15 автоматом заменялось на C:\Temp\[Финдонесение январь 2007 г.1.xls]16


    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:39 17-01-2007
    vzbzdnov



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

    Цитата:
    Если у кого какие мысли  

    Детально довести нет времени, но идея такова - в цикле отнимаем по одной букве спереди и сзади и делаем InStr пока не нашли маску
     
       For bgn = 1 to len(txt2)
           for ln = len(txt2) to bgn step -1
               SearchTxt=Mid(Txt2,bgn,ln)
               If InStr(Txt1,SearchTxt)>0 then
                  Go To GotMask
               end if
            next ln
        next bgn
     
        mask=""
        goto NoMask
    GotMask:
        mask=Left("***********",bgn-1) & SearchTxt & Left("**********",len(txt2)-ln+1)
    NoMask:


    ----------
    |^^^пиво^^\\|""\\_,_
    |___________||___|__|)
    (@)(@)""*|(@)(@)**(@)

    Всего записей: 3957 | Зарегистр. 27-03-2002 | Отправлено: 04:31 17-01-2007 | Исправлено: vzbzdnov, 04:35 17-01-2007
    The okk



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

    Цитата:
    Времени мало, да и нафиг это нужно, разве что развлечения ради

    Да у меня тоже не много - я сейчас тремя задачами на работе одновременно занимаюсь. Просто задача интересная. Я вообще оптимизировать решения люблю, алгоритмы хитрые выдумывать.
     
    ShIvADeSt

    Цитата:
    Как сделать, чтобы при копировании этого листа на имя 16

    Вот эту фразу я не понял... Что значит "копирование листа на имя 16"? Какой лист, откуда копируется и куда копируется?
     
    vzbzdnov
    Такой алгоритм найдет только 1 общий кусок для двух строк. Маску типа file?name для file1name и file2name ему не одолеть.
    При всей кажущейся элементарности задачи алгоритм, если начать разбираться, не так очевиден.
     
    Troitsky

    Цитата:
    ну так ручки же есть - самому нарисовать  

    Самому лениво

    Цитата:
    можно и маску использовать (свойство Mask).  

    Как это облегчит задачу?

    Цитата:
    Как сделаешь - выложи код.

    Ок.
    Что-то не пойму, как тут на OnAction прописать вызов процедуры с параметром? Класс для кнопок что ли создавать
    Но что писать в модуле класса? - Ведь у кнопок на тулбаре нет события Click и способ, который существует для кнопок формы (создать класс кнопок) не подойдет. Простейшая на первый взгляд задача оказалась не такой простой... "Все не только не так просто, но и просто не так"
    Решил сделать слева тулбар с настройкой видимости листов - поскольку их в проекте предполагается до 150, листать их все в поисках нужного довольно нудно. Скрипт, создающий панель я сделал:
    Код:
    Sub AddVisibilityToolBar()
        Dim msBtn As CommandBarButton
        Dim wsList As Worksheet
       'перерисовка панели
        On Error Resume Next
        Application.CommandBars("VisibilityToolBar").Delete
        On Error GoTo 0
        Application.CommandBars.Add(Name:="VisibilityToolBar").Visible = True
        'ставим её слева
        With Application.CommandBars("VisibilityToolBar")
            .Position = msoBarLeft
            'для каждого листа добавляем кнопку
            For Each wsList In Worksheets
                With .Controls
                    Set msBtn = .Add(Type:=msoControlButton)
                    With msBtn
                        .FaceId = 643
                        'на каждой кнопке пишем название соотв. листа
                        .Caption = wsList.Name
                        .Style = msoButtonWrapCaption
                        'если лист видим, кнопка нажата и наоборот
                        .State = wsList.Visible
                    End With
                End With
            Next wsList
        End With
     
    End Sub

    Единственный вопрос: как прописать .OnAction, чтобы при нажатии любой кнопки вызывалась процедура, скажем, btn_click(btn.Caption), где btn.Caption - название кнопки, по которой кликнули. Создавать под каждую кнопку свою процедуру - не рационально.

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 06:58 17-01-2007 | Исправлено: The okk, 12:32 17-01-2007
    Anton T

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

    Код:
     
    Public cmb As CommandBarComboBox
     
    Public Sub ActWs() 'Активация листа
        Worksheets(cmb.List(cmb.ListIndex)).Activate
    End Sub
     
    Public Sub CreateComboBox()
        Dim cb As CommandBar
        Dim ws As Worksheet
     
    '   Удаление существующей панели инструментов Temp
        On Error Resume Next
        Application.CommandBars("Temp").Delete
        On Error GoTo 0
     
    '   Добавление пустой панели инструментов
        Set cb = Application.CommandBars.Add(Name:="Temp", Temporary:=True)
     
    '   Добавление ComboBox и раскрывающегося меню
        Set cmb = cb.Controls.Add(Type:=msoControlComboBox)
         
    '   Проверяем все листы активной книге
        For Each ws In ActiveWorkbook.Worksheets
            cmb.AddItem ws.Name
        Next ws
     
        With cmb
            .DropDownWidth = 100
            .ListIndex = 1
            .OnAction = "ActWs" 'Активация листа
        End With
         
        cb.Visible = True
    End Sub
     

    Проверенно - работает!
     
    Данные на листе отсортированы?
    Бывает да. Ну сделай все , а я потом скажу.

    Всего записей: 325 | Зарегистр. 12-04-2006 | Отправлено: 20:05 17-01-2007
    vzbzdnov



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

    Цитата:
    Такой алгоритм найдет только 1 общий кусок для двух строк

    Тогда так

    Цитата:
     
    Function Mask(Txt1 As String, Txt2 As String) As String
        Dim bgn As Integer, ln As Integer, pos As Integer, strt As Integer
        Dim matchSw As Boolean, SearchTxt As String, s As String
        Mask = ""
        strt = 1
        For bgn = 1 To Len(Txt2)
            matchSw = False
            s = Mid(Txt2, bgn)
            For ln = Len(s) To 1 Step -1
                SearchTxt = Mid(s, 1, ln)
                pos = InStr(strt, Txt1, SearchTxt)
                If pos > 0 Then
                    matchSw = True
                    Exit For
                End If
            Next ln
            If matchSw Then
                Mask = Mask & SearchTxt
                bgn = bgn + Len(SearchTxt) - 1
                strt = pos + Len(SearchTxt)
            Else
                Mask = Mask & "*"
            End If
        Next bgn
    End Function
     


    ----------
    |^^^пиво^^\\|""\\_,_
    |___________||___|__|)
    (@)(@)""*|(@)(@)**(@)

    Всего записей: 3957 | Зарегистр. 27-03-2002 | Отправлено: 01:56 18-01-2007 | Исправлено: vzbzdnov, 04:27 18-01-2007
    ShIvADeSt



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

    Цитата:
    Цитата:Как сделать, чтобы при копировании этого листа на имя 16  
    Вот эту фразу я не понял... Что значит "копирование листа на имя 16"? Какой лист, откуда копируется и куда копируется?

    Лист с формулой имеет имя 15 и ссылаетися в формуле на лист с соотв именем в другой книге (то есть на лист 15) надо чтобы при копироваании Листа с именем 15 в первой книге в имя 16, автоматически в формуле так же менялось имя листа во второй книге с 15 на 16.

    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 04:08 18-01-2007
    SERGE_BLIZNUK

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    vzbzdnov
    Цитата:
    Тогда так  
    красиво... почти работает!
    Но есть косячок - отбрасывает символы в первой строке в начале и конце.
    Например, для
    "Мояпроба9999" и "проба" вернёт маску "проба"
    и ещё, в середине неплохо было бы одиночные звёздочки заменять на "?" а все подряд идущие звёздочки - на одну звездочку. Но это тривиальная задача...

    Всего записей: 2014 | Зарегистр. 12-09-2002 | Отправлено: 06:48 18-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Anton T
    Спасибо, но с комбобоксом проще - это один элемент управления, а тут надо было именно для нескольких контролов одну процедуру, но с разными параметрами.
    На другом форуме подсказали:

    Код:
    Sub AddVisibilityToolBar()
        Dim msBtn As CommandBarButton
        Dim wsList As Worksheet
     
        On Error Resume Next
        Application.CommandBars("VisibilityToolBar").Delete
        On Error GoTo 0
        Application.CommandBars.Add(Name:="VisibilityToolBar").Visible = True
     
        With Application.CommandBars("VisibilityToolBar")
            .Position = msoBarLeft
            For Each wsList In Worksheets
                With .Controls
                    Set msBtn = .Add(Type:=msoControlButton)
                    With msBtn
                        .Caption = wsList.Name
                        .Style = msoButtonWrapCaption
                        .State = wsList.Visible
                        .OnAction = "'MyMacro """ & .Caption & """'"
                    End With
                End With
            Next wsList
        End With
    End Sub
     
    Sub MyMacro(wsName As String)
        With Application.CommandBars("VisibilityToolBar").Controls(wsName)
            .State = Not .State
        End With
        On Error Resume Next
        With Worksheets(wsName)
            .Visible = Not .Visible
        End With
        On Error GoTo 0
    End Sub

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



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

    Цитата:
    Но есть косячок - отбрасывает символы в первой строке в начале и конце.  

    Это не косяк. Просто не вполне понятно, как должно быть.
    Я так понимаю, что маска "проба" означает, что всё слово целиком входит в "Мояпроба9999"
    А, например, МАСК("Мояпро9ба9999","проба")="пр*ба", т.е. буква О никуда не входит
    А МАСК("проба9999","Мояпроба")="***проба", т.е. первые 3 буквы никуда не входят
     
    А как надо, чтоб был ответ?
     


    ----------
    |^^^пиво^^\\|""\\_,_
    |___________||___|__|)
    (@)(@)""*|(@)(@)**(@)

    Всего записей: 3957 | Зарегистр. 27-03-2002 | Отправлено: 07:15 18-01-2007
    The okk



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

    Цитата:
    А как надо, чтоб был ответ?

    Как в шаблоне поиска файла. Там именно для этого такая функция и задумывалась - вместо того, чтобы сохранять большую строку с именами, "законсервировать" их в шаблон. Неизвестное количество символов - *, один символ - ?
    Т.е. МАСК("проба9999","Мояпроба")="*проба*"
     
    Добавлено:
    Массив констант в VBA не задается?

    Всего записей: 327 | Зарегистр. 16-11-2006 | Отправлено: 07:52 18-01-2007
    Troitsky



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

    Цитата:

    Цитата:
    ну так ручки же есть - самому нарисовать
    Самому лениво
    Это уже другое дело.
    Кстати, можно с использованием WinAPI попробовать такое провернуть, но только оправдан ли будет этот геморрой.

    Цитата:

    Цитата:
    можно и маску использовать (свойство Mask).
    Как это облегчит задачу?
    никак не облегчит, но смотреться цивильнее будет.

    Цитата:
    На другом форуме подсказали:
    не забудь обрабатывать добавление в книгу новых листов и их переименование.


    ----------
    Мы в хорошем настроении гуляем по лесам.
    Кто обидеть нас захочет – сам получит по усам.
    Сам полу- получит по усам. Сам полу- получит по усам!

    Всего записей: 795 | Зарегистр. 13-12-2003 | Отправлено: 10:51 18-01-2007 | Исправлено: Troitsky, 10:53 18-01-2007
    The okk



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

    Цитата:
    Кстати, можно с использованием WinAPI попробовать такое провернуть, но только оправдан ли будет этот геморрой.  

    Я WinAPI не юзаю - нет у меня таких задач.

    Цитата:
    никак не облегчит, но смотреться цивильнее будет.

    А для маски все равно нужно рисунок создавать? Я маской никогда не пользовался.
    Пример есть?

    Цитата:
    тогда уж не забудь обрабатывать добавление в книгу новых листов и их переименование.  

    Это понятно. А вот что делать при удалении? Есть какое-то событие, отвечающее за удаление листа?

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

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Подскажите, как суммировать данные в колонке: к примеру каждую четвертую строчку.

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

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    aks_sv
    Цитата:
    Подскажите, как суммировать данные в колонке: к примеру каждую четвертую строчку.
    Вы уверены, что вам нужно решение именно на VBA (макрос)?
    извольте...

    Код:
     
      Row1 = ActiveWorkbook.ActiveSheet.UsedRange.Row
      Row2 = Row1 + ActiveWorkbook.ActiveSheet.UsedRange.Rows.Count - 1
      col1 = Selection.Column
      Sum1 = 0
      For i = Row1 To Row2 step 3
        If TypeName(Cells(i, col1).Value) = "Double" Then
          Sum1 = Sum1 + Cells(i, col1).Value
        End If
      Next i
      MsgBox "Summa = " + Str(Sum1)
     

     

    Всего записей: 2014 | Зарегистр. 12-09-2002 | Отправлено: 11:52 18-01-2007 | Исправлено: SERGE_BLIZNUK, 13:24 18-01-2007
    The okk



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ShIvADeSt
    этот вопрос лучше задать в теме про Excel. По-моему, это должно решаться стандартными средствами через формулу =ЯЧЕЙКА
    Ну, или похожую пользовательскую функцию состряпать, определяющую номер текущего листа:

    Код:
     
    Public Function (rngCell As Range) As Long
    Application.Volatile
    НОМЕР_ЛИСТА = rngCell.Worksheet.Index
    End Function

    Вставь эту формулу в свой проект и потом её используй.
    В качестве аргумента надо указать ячейку. Функция выдаст по этой ячейке номер листа.

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



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Всем привет.
    Есть такая проблема:
    есть листы 1 2 3 print
    заходим на print, а там кнопочка 1 2 3 жмём на неё и печатается соответсвующий лист.
    Как такое реализовать ?
     
    Заранее спасибо.

    Всего записей: 4893 | Зарегистр. 10-11-2004 | Отправлено: 15:57 18-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