Excel VBA Как преобразовать несколько элементов управления и переменных в универсальную функцию - PullRequest
0 голосов
/ 10 мая 2019

У меня есть -userform-, который имеет 100 различных элементов управления (текстовое поле и комбинированный список), и я пытаюсь объединить один большой кусок кода во что-то меньшее и универсальное ... основывая его на активном элементе управления и используя его как моя точка отсчета для вызова другой подпрограммы, где объявленные переменные станут подключи и играй.

Итак, вот базовый код, который работает ... Но мне нужно было бы повторить это 25 раз, и я чувствую, что есть лучший способ, но я не могу понять это ...

Option Explicit

Public Gal, Kg, L, Qt, Pt, Lbs, C, FlOz, Ea, Prts, Oz, Tbs, Tsp, Dl, G, Ml As Integer

Private Sub M1_AfterUpdate() 'this is where the math happens

'I have 25 variables, M1:M25 -  by 16 variables, Gal:Ml for each

Gal = 128: Kg = 35.274: L = 33.814: Qt = 32: Pt = 16: Lbs = 16: C = 8 'multiply
FlOz = 1: Ea = 1: Prts = 1: Oz = 1 'stay
Tbs = 2: Tsp = 6: Dl = 3.381: G = 28.353: Ml = 29.574 'divide

'this is the base code that does ecactly what I need... But i would have to replicate this whole thing 25 times...

    If ActiveControl.Text = "Gal" Then C1.Value = Round(((Q1 * Gal) * (Application.WorksheetFunction.Index(Sheets("Inventory").Range("C6:L1006"), _
                                                Application.WorksheetFunction.Match(I1, Sheets("Inventory").Range("C6:C1006"), 0), 10))), 2)

    If ActiveControl.Text = "Kg" Then C1.Value = Round(((Q1 * Kg) * (Application.WorksheetFunction.Index(Sheets("Inventory").Range("C6:L1006"), _
                                                Application.WorksheetFunction.Match(I1, Sheets("Inventory").Range("C6:C1006"), 0), 10))), 2)

    If ActiveControl.Text = "L" Then C1.Value = Round(((Q1 * L) * (Application.WorksheetFunction.Index(Sheets("Inventory").Range("C6:L1006"), _
                                                Application.WorksheetFunction.Match(I1, Sheets("Inventory").Range("C6:C1006"), 0), 10))), 2)

' it goes on through each of the variables but i post it all, you get the idea ; )

End Sub

Я пробовал эту дорогу ... ЭТО НЕ БЫЛО !!! Я не мог понять, как читать его как имя элемента управления, он читается как строка.

Я попытался поместить панель управления / управления спереди, и это не сработало ...

Option Explicit

Public Gal, Kg, L, Qt, Pt, Lbs, C, FlOz, Ea, Prts, Oz, Tbs, Tsp, Dl, G, Ml As Integer

Private Sub M1_AfterUpdate() 'this is where the math happens
Dim ActCtrl As Control: Set ActCtrl = ActiveControl.Name
Dim VarA As Integer
Dim x, y, z As String

If ActCtrl = M1 Then VarA = 1 ' 25 if lines written to represent 25 rows of form controls
'M2 is VarA=2 and so on till 25

'this puts them together, but it returns string.
    x = "I" & VarA
    y = "Q" & VarA
    z = "C" & VarA

    'this is where it would end
    z.Value = Round(((y * Ml) * (Application.WorksheetFunction.Index(Sheets("Inventory").Range("C6:L1006"), _
                                Application.WorksheetFunction.Match(x, Sheets("Inventory").Range("C6:C1006"), 0), 10))), 2)

Я бы хотел изменить это ...

    If ActiveControl.Text = "Gal" Then C1.Value = Round(((Q1 * Gal) * (Application.WorksheetFunction.Index(Sheets("Inventory").Range("C6:L1006"), _
                                                Application.WorksheetFunction.Match(I1, Sheets("Inventory").Range("C6:C1006"), 0), 10))), 2)

подключи и играй, используя переменные ... Если возможно ...

Ответы [ 2 ]

0 голосов
/ 10 мая 2019

Так что, если кто-то сталкивается с чем-то вроде этого, вот исправление ... Еще раз спасибо за напоминание, что есть простой способ!

Шаг 1. Создайте инструмент на рабочем листе ...Смотрите картинку.Я использовал серию index / match для моего ... Но что когда-нибудь вам нужно ...

Инструмент рабочего листа ...

Шаг 2: Вв отдельном модуле есть этот бит ... Этот код говорит прямо к инструменту.

Option Explicit

Sub Conv_Loop()
Dim CtrlName

CtrlName = RecipeCost.CtrlName

    Sheets("Control").Range("C24").Value = RecipeCost.Controls("I" & CtrlName).Value
    Sheets("Control").Range("C25").Value = RecipeCost.Controls("Q" & CtrlName).Value
    Sheets("Control").Range("C26").Value = RecipeCost.Controls("M" & CtrlName).Value

    RecipeCost.Controls("C" & CtrlName).Value = Sheets("Control").Range("C28").Value

End Sub

Шаг 3: В пользовательской форме с переменными, которые должны общаться с менеджером преобразования, сначала объявите открытую переменную,Затем в элементе управления вы хотите активировать функцию, поместите объявление вашей переменной, а затем просто вызовите ее.Если вы не хотите видеть инструмент или делать его доступным для других, установите для листа значение xlVeryHidden.

Option Explicit

Public CtrlName

Private Sub M1_AfterUpdate(): CtrlName = 1: Call Conv_Loop: End Sub

Это заняло мир глупостей, который я пытался сделать, и сделало его очень легким !!!

Привет Тиму Уильямсу за то, что он напомнил мне ... "Создай дватаблица поиска на листе ", вот и все ...

0 голосов
/ 10 мая 2019

Создайте таблицу поиска из двух столбцов на листе, используя Единицы измерения и Коэффициент преобразования, и используйте vlookup для прямого преобразования единиц измерения в значение масштабирования.

Затем выведите почти весь код из вашего M1_AfterUpdate в общие методы, в которые вы можете просто передать M1 и т. Д.

Что-то вроде этого:

Private Sub M1_AfterUpdate() 
    HandleCombo M1 
End Sub

Private Sub M2_AfterUpdate() 
    HandleCombo M2 
End Sub
'etc for other combos


'handle a combo box changing
Sub HandleCombo(cmbo)
    Dim f, c as object
    f = GetScalingFactor(cmbo.Text)
    Set c = me.Controls(Replace(cmbo.Name, "M", "C")) 'corresponding text control
    c.Value = 'long formula which uses f
End Sub

'convert unit to scaling factor
Function GetScalingFactor(unit)
    Dim m, rv
    m = Application.Vlookup(unit, _
                            thisworkbook.sheets("lookup").Range("A2:B26"), _
                            2, False)
    If not iserror(m) then
        rv = m
    else
        'no match on the unit name - what to do here?
        rv = -1 'or raise an error
    end if
    GetScalingFactor = rv
End function
...