How can I write this VBA code more efficient? - vba

is there a possible way to write this piece of VBA code more efficient?
With the use of for loops or so?
And make it more general, not with the fixed cells?
Private Sub CommandButton1_Click()
Range("A31").Formula = "=index(Optional_Processes,1)"
Range("A32").Formula = "=index(Optional_Processes,2)"
Range("A33").Formula = "=index(Optional_Processes,3)"
Range("A34").Formula = "=index(Optional_Processes,4)"
Range("A35").Formula = "=index(Optional_Processes,5)"
Range("A36").Formula = "=index(Optional_Processes,6)"
Range("A37").Formula = "=index(Optional_Processes,7)"
Range("A38").Formula = "=index(Optional_Processes,8)"
Range("A39").Formula = "=index(Optional_Processes,9)"
Range("A40").Formula = "=index(Optional_Processes,10)"
Range("A41").Formula = "=index(Optional_Processes,11)"
Range("A42").Formula = "=index(Optional_Processes,12)"
Thanks!

Another way to do it in one hit would be:
Private Sub CommandButton1_Click()
Range("A31:A42").Formula = "=index(optional_processes,row()-30)"
End Sub
This wouldn't put 1,2,3 etc as the last argument but when placed on row 31 it will return 1 (row()-30) and so on.

Using a For loop, like this:
Dim i As Long
For i = 2 To 12
Range("A" & 30 + i).Formula = "=index(Optional_Processes," & i & ")"
Next i
2nd Option:
Dim CellStart As Range
Set CellStart = Range("A30") ' set the Start Cell anchor
For i = 2 To 12
CellStart.Offset(i).Formula = "=index(Optional_Processes," & i & ")"
Next i

Related

Excel VBA: How to use a variable for VisibleItemsList?

I'm trying to control a Pivot table's filter by using VBA and I'm struggling to correctly using the "VisibleItemsList" with a variable that contains the filters settings, I'll post the code for a better understandig:
Public Sub updatePivotTable(param2Set() As Variant)
'Array("[Budget].[AM].&[Aeffe USA]","[Budget].[AM].&[Alberganti]","[Budget].[AM].&[Blokh]","[Budget].[AM].&[Bondi]")
Dim y As Integer
Dim parametersCount As Integer
parametersCount = UBound(param2Set)
Dim filters As String
'filters = "Array("
For y = 0 To parametersCount - 1
filters = filters + """[Budget].[AM].&[" & param2Set(y) & "]"", "
Next y
filters = filters + """[Budget].[AM].&[" & param2Set(y) & "]"""
With Sheets("Export BUDG")
.PivotTables("pvtToExport").PivotFields("[Budget].[AM].[AM]").VisibleItemsList = Array(filters)
End With
End Sub
The error I get is:
Query (1, 28) Sintax ',' incorrect. ("[Budget].[AM].&[Caprioli]",
"[Budget].[AM].&[Bondi]")."
Can anyone point me in the right direction? Thanks.

Compare 3 Columns in Excel using VBA

I want to compare 2 to 1 Columns in Excel using VBA..
I already achieve 2 to 2 Columns using this code
Sub LIST1_LIST2()
Dim list1 As Range
Dim LIST2 As Range
Set list1 = Range("B3:C181")
Set LIST2 = Range("G3:H729")
For Each row1 In list1.Rows
For Each row2 In LIST2.Rows
If (row1.Cells(1) = row2.Cells(1) And row1.Cells(2) = row2.Cells(2)) Then
row1.Cells(1).Offset(0, 2) = row1.Cells(1)
row1.Cells(2).Offset(0, 2) = row1.Cells(2)
Exit For
End If
Next row2
Next row1
End Sub
But now I need something VBA scripts that works somehow like the image below
Work with a a simple Do Until Loop:
Option Explicit
Public Sub Example()
Dim B As Range, _
C As Range, _
D As Range, _
F As Range, _
G As Range
Dim i%, x% ' Dim as long
Set B = Columns(2)
Set C = Columns(3)
Set D = Columns(4)
Set F = Columns(6)
Set G = Columns(7)
i = 2
x = 2
Do Until IsEmpty(B.Cells(i))
Debug.Print B.Cells(i).Value & ", " & _
C.Cells(i).Value ' Print on Immed Win
Do Until IsEmpty(F.Cells(x))
DoEvents ' For testing
If F.Cells(x).Value = B.Cells(i).Value & ", " & _
C.Cells(i).Value Then
Debug.Print F.Cells(i).Value = B.Cells(i).Value & ", " & _
C.Cells(i).Value ' Print on Immed Win
G.Cells(x) = D.Cells(i)
x = 2 ' Reset Loop
Exit Do
End If
x = x + 1
Loop
i = i + 1
Loop
End Sub
Other info
DoEvents is most useful for simple things like allowing a user to cancel a process after it has started, for example a search for a file. For long-running processes, yielding the processor is better accomplished by using a Timer or delegating the task to an ActiveX EXE component.. In the latter case, the task can continue completely independent of your application, and the operating system takes case of multitasking and time slicing.
Debug.Print Immediate Window is used to debug and evaluate expressions, execute statements, print variable values, and so forth. It allows you to enter expressions to be evaluated or executed by the development language during debugging. To display the Immediate window, open a project for editing, then choose Windows from the Debug menu and select Immediate, or press CTRL+ALT+I.
You can use this pseudocode to guide you:
If LASTNAME = Left(NAME,LASTNAME.Length) And _
FIRSTNAME = Right(NAME,FIRSTNAME.Length) Then

VBA get dynamically names of component?

I am newbie in vb and I am trying to write simple programs in Excel 2010.
I have a multipage with customers(cutomer1, customer2, ..., customer20)
For each customer I have 10 users "labels" with their textboxes.
The textboxes are filled from a sheet page customer1 B9:B18 , customer2 D9:D18, etc ...
Is there any way to get dynamically the names and the values in order to avoid code like the following ?
CUSTOMER1_USER1_TEXTBOX.Value = Sheets("Data").Range("B9").Value
CUSTOMER1_USER2_TEXTBOX.Value = Sheets("Data").Range("B10").Value
CUSTOMER1_USER3_TEXTBOX.Value = Sheets("Data").Range("B11").Value
CUSTOMER1_USER4_TEXTBOX.Value = Sheets("Data").Range("B12").Value
CUSTOMER1_USER5_TEXTBOX.Value = Sheets("Data").Range("B13").Value
CUSTOMER1_USER6_TEXTBOX.Value = Sheets("Data").Range("B14").Value
CUSTOMER1_USER7_TEXTBOX.Value = Sheets("Data").Range("B15").Value
CUSTOMER1_USER8_TEXTBOX.Value = Sheets("Data").Range("B16").Value
CUSTOMER1_USER9_TEXTBOX.Value = Sheets("Data").Range("B17").Value
CUSTOMER1_USER10_TEXTBOX.Value = Sheets("Data").Range("B18").Value
CUSTOMER2_USER1_TEXTBOX.Value = Sheets("Data").Range("D9").Value
CUSTOMER2_USER2_TEXTBOX.Value = Sheets("Data").Range("D10").Value
CUSTOMER2_USER3_TEXTBOX.Value = Sheets("Data").Range("D11").Value
CUSTOMER2_USER4_TEXTBOX.Value = Sheets("Data").Range("D12").Value
CUSTOMER2_USER5_TEXTBOX.Value = Sheets("Data").Range("D13").Value
CUSTOMER2_USER6_TEXTBOX.Value = Sheets("Data").Range("D14").Value
CUSTOMER2_USER7_TEXTBOX.Value = Sheets("Data").Range("D15").Value
CUSTOMER2_USER8_TEXTBOX.Value = Sheets("Data").Range("D16").Value
CUSTOMER2_USER9_TEXTBOX.Value = Sheets("Data").Range("D17").Value
CUSTOMER2_USER10_TEXTBOX.Value = Sheets("Data").Range("D18").Value
......
Could you help me please do it ?
Thanks
Something like this should work:
Private Sub UserForm_Initialize()
Dim i As Long, j As Long
With Sheets("Data")
For i = 1 To 20
For j = 1 To 10
Me.Controls("CUSTOMER" & i & "_USER" & j & "_TEXTBOX").Value = .Cells(j+8, 2*i).Value
Next j
Next i
End With
End Sub

Excel VBA Getting a multiple selection from a listbox

I have a listbox which I set to selectmulti
I am trying to get the values of the selected items with this :
Private Sub CommandButton3_Click()
Dim lItem As Long
Dim nboc As Integer
Dim c As Integer
Range("G:G").Clear
nboc = Worksheets("BDD").Range("IQ2").Value
c = 0
For lItem = 0 To ListBox2.ListCount - 1
If ListBox2.Selected(lItem) = True Then
c = c + 1
Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = ListBox2.List(lItem)
ListBox2.Selected(lItem) = False
End If
Next
End Sub
This works as long as I have one item selected. If I have x items selected, it returns x times the first item.
Can you help me?
(I am fairly new to VBA and am trying to learn on my own)
With this line:
Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = ListBox2.List(lItem)
you override the values previously printed by this function.
In first iteration you print the value in each cell of range G15:G15 (a single cell in this case), in second iteration you print the value in each cell of range G15:G16 (so you override the value printed in first iteration) and so on.
You need to change this line like below:
Worksheets("Bordereau Prep").Range("G14").Offset(c, 0) = ListBox2.List(lItem)
Your problem is in the line:
Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = ListBox2.List(lItem)
It simply assigns the whole range to the last found value. Here is something that works for you, you may use it somehow further and change it.
Option Explicit
Sub btn()
Dim lItem As Long
Dim c As Long
Range("G:G").Clear
For lItem = 0 To Worksheets("Bordereau Prep").ListBox2.ListCount - 1
If Worksheets("Bordereau Prep").ListBox2.Selected(lItem) = True Then
c = c + 1
Worksheets("BDD").Cells(15 + c, 7) = Worksheets("Bordereau Prep").ListBox2.List(lItem)
'Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = Worksheets("Bordereau Prep").ListBox2.List(lItem)
Worksheets("Bordereau Prep").ListBox2.Selected(lItem) = False
End If
Next lItem
End Sub
Last but not least, you try not to use Integers in VBA, but longs. Enjoy it!

Scope of Cell Object in For Loop - VBA

I'm working on a bit of VBA that's intended to loop over a Schedule Builder for students made in Excel. I keep getting an Error 424 during the assignments c = c.Offset(X, 0), but only in the nested For loops. Is there a limited scope, and if so, how do I overcome it?
Below is the code:
Public Sub generateRosters()
Worksheets("Course Rosters").Cells.ClearContents
Worksheets("Course Rosters").Range("A1") = "Course"
Worksheets("Course Rosters").Range("B1") = "Room"
Dim classTitleRange As Range
Set classTitleRange = Worksheets("Master School Schedule").Range("D1:BN1")
Dim rowCount As Integer
rowCount = 2
Dim periodArr(1 To 8) As String
periodArr(1) = "A"
periodArr(2) = "B"
periodArr(3) = "C"
periodArr(4) = "D"
periodArr(5) = "E"
periodArr(6) = "F"
periodArr(7) = "G"
periodArr(8) = "Z"
For Each c In classTitleRange.Cells
Dim courseTitle As String
courseTitle = c
c = c.Offset(2, 0)
Dim room As String
room = c
For Each p In periodArr()
Dim offsetCount As Integer
offsetCount = 0
For i = 1 To 340
c = c.Offset(1, 0) '424 Error One
If c = p Then
End If
offsetCount = offsetCount + 1
Next
c = c.Offset(-offsetCount, 0) '424 Error Two
Next
Worksheets("Course Rosters").Range("A" & rowCount) = "'" & courseTitle
Worksheets("Course Rosters").Range("B" & rowCount) = room
rowCount = rowCount + 1
Next
End Sub
Thanks, for your help.
Edit: Side question, is there a way for me to create a variable that I can manipulate like c, but not be c. Basically a Dim d As (Something) followed by d = c. I can't seem to find the right object to assign to d, so that I can make it c. Thanks again.
I don't get logic and goal of your code therefore there are only some tips for you:
c=c.offset(2,0)
changes initial Range type c variable into empty or any other value.
Next you try to use, in the line with error, the same c variable as range object which is not allowed.
What you possibly need is the Set instruction in the following lines:
Set c= c.offset(2,0)
'....
Set c= c.offset(1,0)
But as I said, I don't know the complete logic therefore this is solution for the error you have but not sure if it solve all your problems.