Страницы: 1
RSS
Выбор диапазона ячеек макроса через userform/combobox
 
Я сделал простенький Userform для прикрепленного примера макроса, подскажите код чтобы через combobox выбирать диапазон ячеек, которые прописаны в модуле данного макроса.
Код
Опора_Объед Application.Intersect( _
     .UsedRange, .Range("F10:F9999"))  

вот этот код чтобы можно было выбирать через combobox.
 
допустим вы выбрали в комбобоксе этот код (формально, это код, фактически это текст) и что с ним делать дальше???
диапазон лучше выбирать с помощью InputBox
см.вложение
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Baguza написал:
Range("F10:F9999"))      -      вот этот код чтобы можно было выбирать через combobox
Поясните пожалуйста, это всегда должен быть диапазон "F10:F9999" или тоже какой-то другой внутри него ?
 
Baguza,
у вас созрел план написания очень универсального кода, но тут  оказалось непонятно как из комбобокса  извлечь вот это:
Опора_Объед Application.Intersect( _
    .UsedRange, .Range("F10:F9999"))  
а давайте допустим строка уже извлечена в переменную, напишите в коде:
CodeStr = "Опора_Объед Application.Intersect(UsedRange, .Range("F10:F9999"))"
все! у вас в CodeStr есть желанная строка и вот тут возникает РЕАЛЬНАЯ проблема, а что с ней делать??!!!
как воспользоваться этой строкой? чем она (это строка) вам поможет?
проблема не в извлечении строки из комбобокса, а проблему нужно сначала сформулировать, а потом уже можно будет и решать
(а как выбрать диапазон, я показал в сообщении выше)
Изменено: Ігор Гончаренко - 10.12.2019 03:28:31
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
ocet p написал: Поясните пожалуйста, это всегда должен быть диапазон "F10:F9999" или тоже какой-то другой внутри него ?
Это условный диапазон. Для разных таблиц он будет разный. Я хотел бы, чтобы его (диапазон) можно было бы изменять через меню пользовательской формы, чтобы каждый раз не лезть в код макроса.

Цитата
Ігор Гончаренко написал: у вас созрел план написания очень универсального кода
Код написали добрые форумчане. Я в макросах четвертый день. Поэтому пока особо не разбираюсь, что и как тут работает. Пытаюсь сделать удобную форму ввода данных для просчета макросом.

Цитата
(а как выбрать диапазон, я показал в сообщении выше)
Смысл в том, чтобы выбранный диапазон изменял значение этого кода:
Код
Опора_Объед Application.Intersect( _
    .UsedRange, .Range("F10:F9999"))  

Не принципиально будет ли это combobox или inputbox цель заключается в том, чтобы этот ***box находился на "пользовательской форме" и выполнял функцию описанную выше.

p.s. Если я в связи со своей неопытностью как то не так изъясняюсь, то уж простите)) могу только своими словами
 
Цитата
Baguza написал:
(диапазон) можно было бы изменять через меню пользовательской формы
Цитата
Baguza написал:
Смысл в том, чтобы выбранный диапазон изменял значение этого кода


1. Создайте "TextBox" (или "InputBox" как вам написал Ігор Гончаренко), чтобы ввести диапазон для листов, которые могут еще не существовать или для динамических диапазонов.
2. Для других, постоянно присутствующих листов, создайте константы (или переменные), которые будут хранить строго определенный диапазон.
3. Вы будете ссылаться на них например через конструкции с "IF" или "Select Case".

Может быть, вот так это можно сделать ?

Код
Option Explicit

'Dlya Variant 2
Const diap_resurs = "A10:A9999"
Const diap_VED = "B10:B9999"
Const diap_LRV = "E10:E9999"
Const diap_lokalka = "F10:F9999"

Private Sub UserForm_Initialize()
    '...
End Sub

'Variant 1 - Fiksirovannyy diapazon dlya vsekh
Private Sub CommandButton1_Click()
    With UserForm1
        With .ComboBox4
            If .ListIndex = -1 Then
                MsgBox ("Vyberite list c lokalkoy")
                Exit Sub
            End If
            
            If .Parent.CheckBox1.Value = True Then
                Call Opora_Obed_RUN(.List(.ListIndex), "F10:F9999")
            End If
        End With
    End With
End Sub

'Variant 2 - Peremennyy diapazon dlya postoyanno prisutstvuyushchikh listov
Private Sub CommandButton1_Click()
    With UserForm1
        With .ComboBox4
            If .ListIndex = -1 Then MsgBox ("Vyberite list c lokalkoy"): Exit Sub
            
            Dim diap$, Lst$: Lst = .List(.ListIndex)
        End With
        
        Select Case Lst
            Case "resurs":  diap = diap_resurs
            Case "VED":     diap = diap_VED
            Case "LRV":     diap = diap_LRV
            Case "lokalka": diap = diap_lokalka
        End Select
        
        If .CheckBox1.Value = True Then Call Opora_Obed_RUN(Lst, diap)
    End With
End Sub

'Variant 3 - Dlya "TextBox"
Private Sub CommandButton1_Click()
    With UserForm1
        If Trim(.TextBox1.Text) = "" Then MsgBox ("Vpishite chto-nibud' v 'TextBox1'"): Exit Sub
        
        With .ComboBox4
            If .ListIndex = -1 Then MsgBox ("Vyberite list c lokalkoy"): Exit Sub
            
            If .Parent.CheckBox1.Value = True Then Call Opora_Obed_RUN(.List(.ListIndex), Trim(.Parent.TextBox1.Text))
        End With
    End With
End Sub

Sub Opora_Obed_RUN(shList$, rngDiap$)
    Dim rsltRng As Range
    
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
    With Sheets(shList)
        Set rsltRng = Intersect(.UsedRange, .Range(rngDiap))
        If Not rsltRng Is Nothing Then
            Call Opora_Obed(shList, rsltRng)
            .Calculate
        Else
            '... chto-to tam
            MsgBox "Net takogo diapazona"
            '... chto-to tam
            Exit Sub
        End If
    End With
    
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub
 
Прошу прощения, видимо я все таки, что то не так объяснил.

Вот посмотрите пожалуйста на скриншот пользовательской формы и на вопросы по номерам
Номер 1 - В этом поле я хочу изменять диапазон  ячеек кода, который написан ниже (это основной вопрос по данной теме, что меня интересует)
Код
Опора_Объед Application.Intersect( _
    .UsedRange, .Range("F10:F9999"))  
например выбираю в окне "С" F10 в окне "ПО" F214. И получаю в итоге в коде  .UsedRange, .Range("F10:F214"))

Номер 2 - В окне "выберите лист с локалкой" тот лист, на котором я этот диапазон выбираю (этот диапазон нужен только для этого листа и ни для какого больше). В файле-примере этот лист называется "локалка".

Номер 3 - флажок, который будет запускать данную функцию на выбранном листе и на выбранном диапазоне.

Номер 4 - ну тут все понятно. Кнопка запуска расчета по заданным параметрам. В случае если параметры не внесены расчет не запускается.
 
1. Что было бы источником данных для этих "ComboBox" ?
2. Почему "выбирать" эти данные в "Combobox" а не вводить их вручную в одно или два поля типа "TextBox" ?
3. Процедуры будут очень похожи
 
Цитата
ocet p написал:
1. Что было бы источником данных для этих "ComboBox" ?
У меня готовая таблица (как в примере) только без формул. Я запускаю макрос в своей уже готовой таблице, выбираю лист (к примеру "локалка") данные уже находятся на этом листе в ячейках "F10:F ..." - ну до конца таблицы (всегда по разному) и макрос мне проставляет формулы для этой таблицы по выбранному мною диапазону. Или я что то не понимаю? Источник данных - цифры в ячейках F
Цитата
ocet p написал:
2. Почему "выбирать" эти данные в "Combobox" а не вводить их вручную в одно или два поля типа "TextBox" ?
Просто мне показалось так удобнее. Если это проблематично сделать, то мне не принципиально чтобы это был Combobox.

Хотелось бы чтобы все было в одном месте (в одной польз. форме например) чтобы не путаться потом и не искать/вспоминать куда мне что вводить.
 
Не в этом дело, речь идёт о том, что чтобы помочь кому-то в чём-то, мы должны понять что он хочет сделать, без этого никакая робота.
Например: почему 'ComboBox1' ("C"), если единственным значением в нём будет начальная ячейка диапазона, одинаковая для всех листов, то есть "F10" ?
Не лучше ли иметь простой текстовый ярлык с описанием "F10" ?
Или может быть для разных листов будут разные столбцы с данными, не для каждого "F" (лист 'VED' не имеет столбца "F") ?
Только как отличить это тогда ?
Столбцы данных (буквы столбцов) будут постоянно назначены на листы ?
 
ocet p, расчеты этого кода
1
2
Опора_Объед Application.Intersect( _
   .UsedRange, .Range("F10:F9999"))
будут производиться только на одном листе. В моем случае-примере  -  это лист "локалка". Остальные листы никак не будут (не должны быть) задействованы в данном расчете. Но чтобы подстраховаться, что это может не всегда будет столбец "F" и не всегда он будет начинаться с "F10" я и решил добавить  'ComboBox1' ("C").

Другими словами, Лист будет какой то один и столбец будет какой то один единственный. Мне нужно только выбрать какой это будет лист (локалка) и какой столбец (где у него начинается диапазон и где заканчивается) чтобы запустить этот код только там и нигде больше.  
 
Baguza,
См. #2. там написано как выбрать диапазлн, чтобы запустить расчет в нем и нигде больше
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Baguza написал:
нужно только выбрать какой это будет лист (локалка) и какой столбец (где у него начинается диапазон и где заканчивается)
Ещё никто не ответил ?
Может так ?

UserForm:
Код
Option Explicit

Const nazvLst = "lokalka", diapLst = "F10:F9999"

Dim cb1 As ComboBox, cb2 As ComboBox, cb3 As ComboBox, cb4 As ComboBox

Private Sub UserForm_Initialize()
    Dim sht As Worksheet
    
    With UserForm1
        Set cb1 = .ComboBox1: Set cb2 = .ComboBox2
        Set cb3 = .ComboBox3: Set cb4 = .ComboBox4
    End With
    
        cb1.AddItem Split(diapLst, ":", -1, 1)(0)
        cb2.AddItem Split(diapLst, ":", -1, 1)(1)
    
    For Each sht In ThisWorkbook.Sheets
        cb3.AddItem sht.Name
        cb4.AddItem sht.Name
    Next
End Sub

Private Sub CommandButton1_Click()
    If cb1.ListIndex = -1 Or cb2.ListIndex = -1 Or cb4.ListIndex = -1 Then GoTo EineGrosseOshiba
    
    If Me.CheckBox1.Value Then
        Dim diapC$: diapC = cb1.List(cb1.ListIndex)
        Dim diapPO$: diapPO = cb2.List(cb2.ListIndex)
        
        Call Opora_Obed_RUN(nazvLst, diapC & ":" & diapPO)
    'Else
    '    MsgBox ("Poproshu flazhka dlya 'Proschitat ob'emy'") ' => ???
    End If
    
Exit Sub
EineGrosseOshiba: MsgBox ("Oyoyoy ! Vyberite dannyye iz spiskov")
End Sub

Стандартный модуль:
Код
Option Explicit

Sub Opora_Obed_RUN(shList$, rngDiap$)
    Dim yos&
    Dim rsltRng As Range, yach As Range
    
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
    With Sheets(shList)
        Set rsltRng = Intersect(.UsedRange, .Range(rngDiap))
        
        If Not rsltRng Is Nothing Then
            For Each yach In rsltRng.Cells
                If yach.MergeCells Then
                    yos = yach.Row
                Else
                    If yos > 0 Then yach.FormulaR1C1 = "=RC[-1]*R" & yos & "C[-1]"
                End If
            Next
            .Calculate
        End If
    End With
    
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub
 
ocet p, ошибку выдает((    "Subscript out of range"
 
Цитата
Baguza написал:
Ещё никто не ответил ?
а смысл?
тут нужны не точечные подсказки, а брать весь проект целиком и выдать обратно полностью рабочий вариант
кому будет интересно выяснит у автора условия задачи, напишет все, завяжет сверху красивым голубеньким бантиком (т.е. модули лучше запаролить) и попросит пользоваться не развязывая его
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Baguza написал:
ошибку выдает
Но где в какой строке кода ?   ... :() ?

Цитата
Ігор Гончаренко написал:
тут нужны не точечные подсказки, а брать весь проект целиком
А что с самообразованием автора темы на основе советов форума ? :)  
 
Цитата
ocet p написал: Но где в какой строке кода ?   ... ) ?
Код
Sub Opora_Obed_RUN(shList$, rngDiap$)
    Dim yos&
    Dim rsltRng As Range, yach As Range
     
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
     
With Sheets(shList)   ' вот эта строка
        Set rsltRng = Intersect(.UsedRange, .Range(rngDiap))

Когда меняю диапазон то  ошибку выдает "выберите данные из списков"  когда запускаю с диапазоном F10:F9999 то выдает вот эту ошибку  "Subscript out of range"
 
Ігор Гончаренко, Уважаемый, я по моему в своих сообщениях изначально обозначил, что я с макросами только начал работать и не имею опыта. И тема называется не "напишите для меня проект целиком, а то я сам ничего не хочу делать и не понимаю", а конкретно по определенной задаче.

а что касательно:
Цитата
См. #2. там написано как выбрать диапазлн, чтобы запустить расчет в нем и нигде больше
это не решение задачи - это пример того, как еще больше меня запутать и переубедить меня в надобности создания той формы (пользовательской), с которой мне последующем будет удобно работать.
 
Вы изменили латинские названия листов на кириллицу ?
Покажите ваш конвертированный код для обзора.
 
#2 никаким боком не относится к вашей форме - ни сколько не отрицает и ни чуть не поощряет использование  этой формы и любых других
#2 показывает как выбрать диапазон с любого листа, любой книги, и как потом воспользоваться тем, что выбрано
привяжете вы этот способ к своей форме, создадите на его основании пользовательскую функцию и воспользуетесь любым другим способом - это ваше личное дело, кстати, точно такое жн личное, как забить на эту подсказку и придумать что-то свое, белее удобное, универсальное и эффективное по сравнению с предложенным мною убогим способом
Цитата
Baguza написал:
Выбор диапазона ячеек макроса через userform/combobox
если из названия вашей темы выкинуть "через userform/combobox"
то пример как раз отвечает на вопрос:  "Выбор диапазона ячеек макросом"
понимаете, можно, собрав большую бригаду строителей с помощью медицинских бинтов поднять железобетонную плиту перекрытия и установить ее на место монтажа, а можно для этого использовать подьемный кран и спропы, - зацепить и поставить на место
в случае с "Выбор диапазона ячеек макроса через userform/combobox" вы не рискуете жизнями бригады строителей и можете продолжать эксперименты, пока все не получиться (если поставить такую цель - можно найти тысячи разных вариантов, как сделать это с помощью юзерформ и комбобокса в ней)))
Изменено: Ігор Гончаренко - 12.12.2019 02:59:27
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
ocet p написал:
Вы изменили латинские названия листов на кириллицу ?
Да, простите. Тут уже понял. Лист должен был называться "lokalka" чтобы функция заработала. Она и заработала.
Теперь с диапазоном не понятно. Как его изменить? Он по умолчанию F10:F9999. При других значениях не считает
 
Цитата
Baguza написал:
Теперь с диапазоном не понятно. Как его изменить?
в #2 показано как выбрать ЛЮБОЙ диапазон, присвоить переменной, и как потом выбранный диапазон использовать в дальнейших расчетах
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Baguza написал:
должен был называться "lokalka"
Имя может быть любым, но как лист, так и содержимое константы "nazvLst" (Const nazvLst = "lokalka") должны совпадать (лист = "Локалка" => Const nazvLst = "Локалка", лист = "Пёс Барбос" => Const nazvLst = "Пёс Барбос", и т.д.)

Цитата
Baguza написал:
с диапазоном не понятно. Как его изменить?
Здесь вы должны объяснить, как надо сделать такой список. На каких критериях это должно основываться ?
Должны ли они быть, например, все буквы алфавита, или, может быть, просто буквы столбцов из области "UsedRange", и т.д. ?
Я не знаю, что вы намерены в этом отношении.

Вы можете увидеть здесь недостатки "ComboBox" для таких операций, нормальное текстовое поле было бы намного лучше чтобы вводить в неё диапазон.
Или может быть, например, комбинация "ComboBox" и "SpinButton", или метод Игоря Гончаренко ?


 
Цитата
ocet p написал:
Здесь вы должны объяснить, как надо сделать такой список. На каких критериях это должно основываться ?Должны ли они быть, например, все буквы алфавита, или, может быть, просто буквы столбцов из области "UsedRange", и т.д. ?Я не знаю, что вы намерены в этом отношении.Вы можете увидеть здесь недостатки "ComboBox" для таких операций, нормальное текстовое поле было бы намного лучше чтобы вводить в неё диапазон.Или может быть, например, комбинация "ComboBox" и "SpinButton", или метод Игоря Гончаренко ?
Если бы можно было использовать или как то связать метод Игоря Гончаренко с моей пользовательской формой, то было бы замечательно. Нет никакой принципиальности, что именно использовать. Текстовое поле вполне подойдет. Можно его разместить на пользов.форме?  
 
Baguza, можно было обойтись и без цитирования. Вот я пишу без цитаты - понятно, к кому я обращаюсь?
Почему Вы упорно отказываетесь от Application.InputBox? Ведь с его помощью элементарно выбирается нужный диапазон прямо на листе.
Страницы: 1
Наверх