Literally first time in two decades I've done this and that was even super basic (no pun intended). I have Sheet1 ("Main Page") that I am copying data from ("Control Sequences") based on data entered in Column B. I have it sort of working. The issue I will run into is when I copy over the first set of data, then want to bring in another set, the code runs for the whole sheet again and overwrites any tweaks I did previously. I want to be able to bring in a set of data to Sheet1, manually skip a couple of rows, type in another value in column B below that, re-run the code and append new data in. I'll try to come up with a simpler explanation if this doesn't make sense. Brain is fried right now after 5 hours of VBA absorption :P Here is the code I have so far in its entirety (It's sort of brute force so beware):
Sub test()
Dim i As Integer 'Main Page Sheet Row Number
Dim n As Integer 'Control Sequences Sheet Row Number
Dim x As Integer 'Main Page Current Row Number
Dim y As Integer 'Column Number
Dim CSrow As Integer 'Current Row
Dim NextCS As Integer 'Next Control Sequence
Dim NextCSrow As Integer 'Row To Stop At
Dim ws1 As Worksheet 'Var
Dim ws2 As Worksheet 'Var
Set ws1 = Worksheets("Main Page")
Set ws2 = Worksheets("Control Sequences")
y = 2
'Cycles through the codes in sheet 1
For i = 2 To ws1.Cells(ws1.Rows.Count, y).End(xlUp).row Step 1
For n = 2 To ws2.Cells(ws2.Rows.Count, y).End(xlUp).row Step 1
If ws1.Cells(i, y).Value = ws2.Cells(n, y).Value Then
x = i
CSrow = ws2.Cells(n, y).row
NextCS = ws1.Cells(i, y).Value + 1
NextCSrow = Application.WorksheetFunction.Match(NextCS, ws2.Range("B1:B200"), 0)
NextCSrow = NextCSrow - 1
For CSrow = CSrow To NextCSrow
y = y + 1
For y = 3 To 7
ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
Next y
' ws1.Cells(x, 8).Formula = ws2.Cells(CSrow, 8).Formula
y = y + 1
ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
y = y + 2
ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
x = x + 1
y = 2
Next CSrow
End If
Next n
Next i
End Sub
Thanks to anyone for your help and input.
EDIT 13 FEB 2014
As mentioned in the comment to the Answer below, I took out the .End(xlUp) piece and it worked. I've also changed the body of the writing loop to this:
For CSrow = CSrow To NextCSrow
' y = y + 1
' For y = 3 To 7
' ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
' Next y
' ws1.Cells(x, 8).Formula = ws2.Cells(CSrow, 8).Formula
' y = y + 1
' ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
' y = y + 2
' ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
' x = x + 1
' y = 2
ws2.Rows(CSrow).Copy Destination:=ws1.Cells(x, 1)
x = x + 1
Next CSrow`
I've got the formatting and the formula to copy over without keeping the original reference :D On to part IV... Testing ALL of the Variables and not just 1 ;) I will continue to update this thread with ... well ... updates.
EDIT 20 FEB 2014
Here's the complete code as it stands now:
Sub test()
Dim i As Long 'Main Page Sheet Row Number
Dim j As Long 'Placeholder
Dim n As Long 'Control Sequences Sheet Row Number
Dim x As Long 'Main Page Current Row Number
Dim y As Long 'Column Number
Dim z As Long
Dim a As Long
Dim CSrow As Long 'Current Row
Dim NextCS As Long 'Next Control Sequence
Dim NextCSrow As Long 'Row To Stop At
Dim ws1 As Worksheet 'Var
Dim ws2 As Worksheet 'Var
Dim ws3 As Worksheet 'Var
Dim ws4 As Worksheet 'Var
' Set ws1 = Worksheets("Main Page")
Set ws1 = ActiveSheet
Set ws2 = Worksheets("Control Sequences")
Set ws3 = Worksheets("Cost 1")
Set ws4 = Worksheets("Cost 2")
If ws1.Name = ws2.Name Or ws1.Name = ws3.Name Or ws1.Name = ws4.Name Then
End
End If
y = 2
z = 10
a = ws1.Cells(ws1.Rows.Count, z).End(xlUp).row + 2
If IsEmpty(ws1.Cells(a, y).Value) Then End
'Cycles through the codes in sheet 1
j = ws1.Cells(ws1.Rows.Count, y).End(xlUp).row
i = ws1.Cells(j, y).row
For i = i To j Step 1
For n = 2 To ws2.Cells(ws2.Rows.Count, y).End(xlUp).row Step 1
If ws1.Cells(i, y).Value = ws2.Cells(n, y).Value Then
x = i
CSrow = ws2.Cells(n, y).row
NextCS = ws1.Cells(i, y).Value + 1
NextCSrow = Application.WorksheetFunction.Match(NextCS, ws2.Range("B1:B100"), 0)
NextCSrow = NextCSrow - 1
For CSrow = CSrow To NextCSrow
' y = y + 1
' For y = 3 To 7
' ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
' Next y
' ws1.Cells(x, 8).Formula = ws2.Cells(CSrow, 8).Formula
' y = y + 1
' ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
' y = y + 2
' ws1.Cells(x, y).Value = ws2.Cells(CSrow, y).Value
' x = x + 1
' y = 2
ws2.Rows(CSrow).Copy Destination:=ws1.Cells(x, 1)
x = x + 1
Next CSrow
End If
Next n
Next i
End Sub
I added a check that if the user was on any of the "Template" sheets, the code would just stop. It's a bit brute force, but it gets the job done and it's the only code I have. Maybe if I continue to do this, I'll try to get more "streamlined". :D Thanks to everyone for their input and help.
I think I have it. Your problem is in the first line of your loop:
For i = 2 To ws1.Cells(ws1.Rows.Count, y).End(xlUp).row Step 1
Try setting i dynamically before the loop begins. DIM another variable j for this, then replace the above line with the following:
j = ws1.Cells(ws1.Rows.Count, y).End(xlUp).row
i = ws1.Cells(j, y).End(xlUp).row
For i = i to j Step 1
While you're at it, change your row integers to long since there are more rows in a worksheet than integers can handle.
Related
New to VBA if someone could help me what im doing wrong here.
Trying to run a loop such that it looks for a specific text, starts the loop then stops at a specific point.
The loops is such that I want it to copy some values below in my sheet hence a is 55.
Im facing the error Block IF without End If
Here is the code:
Private Sub CommandButton3_Click()
For y = 1 To 15 Step 5
Dim x As Double
Dim a As Double
x = 1
a = 55
If Cells(x, y).Value = "Text1" Then
Do Until Cells(x, y).Value = "Text2"
Cells(a, y) = Cells(x, y).Value
Cells(a, y + 1) = Cells(x, y + 1)
x = x + 1
a = a + 1
Loop
End Sub
Indenting is the way forward, you have a for statement with no next and an if with no End If:
Private Sub CommandButton3_Click()
For y = 1 To 15 Step 5
Dim x As Double
Dim a As Double
x = 1
a = 55
If Cells(x, y).Value = "Text1" Then
Do Until Cells(x, y).Value = "Text2"
Cells(a, y) = Cells(x, y).Value
Cells(a, y + 1) = Cells(x, y + 1)
x = x + 1
a = a + 1
Loop
End If
Next y
end sub
Besides the issues I mentioned in the comments to your post, if I understood you correctly, you want to loop on cells at Column A, find the first "Text1", then copy all the cells to row 55 and below, until you find "Text2". If that's the case, try the code below :
Private Sub CommandButton3_Click()
Dim x As Long, y As Long
Dim a As Long
Dim LastRow As Long
With Worksheets("Sheet1") '<-- modify "Sheet1" to your sheet's name
For y = 1 To 15 Step 5
x = 1 '<-- reset x and a (rows) inside the columns loop
a = 55 '<-- start pasting from row 55
LastRow = .Cells(.Rows.Count, y).End(xlUp).Row
While x <= LastRow '<-- loop until last row with data in Column y
If .Cells(x, y).Value Like "Text1" Then
Do Until .Cells(x, y).Value = "Text2"
.Cells(a, y).Value = .Cells(x, y).Value
.Cells(a, y + 1).Value = .Cells(x, y + 1).Value
x = x + 1
a = a + 1
Loop
End If
x = x + 1
Wend
Next y
End With
End Sub
In Excel for Mac:
I have 2 tabs (wkst1 and wkst2) and need to populate a third one (wkst3)
wkst1 has one column with names listed
e.g.
A
B
wkst2 has two columns
X 1
Y 4
I need to populate wkst3 to ensure all rows in wkst2 are associated to each name listed in wkst1.
e.g. my wished result would be:
A X 1
A Y 4
B X 1
B Y 4
Can you suggest the code I should use?
I managed to solve the problem on my own.
Sub writeall()
Dim Ws As Worksheet
Dim Ws1 As Worksheet
Dim Ws2 As Worksheet
Dim X As Long
Dim Y As Long
Dim count As Long
Application.ScreenUpdating = False
Set Ws = ActiveWorkbook.Worksheets(1)
Set Ws1 = ActiveWorkbook.Worksheets(2)
Set Ws2 = Workbooks("xxxx.xlsx").Sheets("2017") ' xxxx is the name of the xlsx
count = 1
For X = 2 To Ws2.Range("A" & Rows.count).End(xlUp).Row
For Y = 1 To Ws1.Range("A" & Rows.count).End(xlUp).Row
count = count + 1
Ws.Cells(count, 1).Value = Ws2.Cells(X, 1).Value
Ws.Cells(count, 2).Value = Ws1.Cells(Y, 2).Value
Ws.Cells(count, 3).Value = Ws1.Cells(Y, 1).Value
Next Y
Next X
Application.ScreenUpdating = True
MsgBox ("Spreadsheet updated")
End Sub
My problem is the as follows:
I have 3 columns and 20 rows, that contains numbers.
There is a line with numbers between 1 to 20 in order crescente, the other cells contains bigger numbers then 100 or whatever.
My homework is that I have to write a VBA code which fill color the cells that contains the line. This way i going to have a "colorful snake" from the cells that contains the numbers between 1 to 20.
Of course, the starting number cell is "A1"
the ending cell can be anywhere in the area "A1:C20"
the substance is the colored cells must have follow the numbers in order cresence!
Sub MeykEhYewowSnakhey()
Dim r, c
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)
For r = 1 To ws.UsedRange.Rows.Count
For c = 1 To ws.UsedRange.Columns.Count
If ws.Cells(r, c).Value < 100 Then
ws.Cells(r, c).Interior.ColorIndex = 6
End If
Next
Next
End Sub
Try that.
There is probably a much more efficient way to solve this but this is my solution.
Sub Snake()
Dim wbk As Workbook
Dim ws As Worksheet
Dim mySnake As Integer, x As Integer, y As Integer
Set wbk = Workbooks("Book1.xlsm")
Set ws = wbk.Worksheets("Sheet1")
x = 1
y = 1
With ws
For mySnake = 1 To 20
If .Cells(x, y) = mySnake Then
.Cells(x, y).Interior.Color = vbYellow
'Check cell below
If .Cells(x + 1, y) = mySnake + 1 Then
x = x + 1
'Check cell to right
ElseIf .Cells(x, y + 1) = mySnake + 1 Then
y = y + 1
'Check cells to left if y <> 1
ElseIf y <> 1 Then
If .Cells(x, y - 1) = mySnake + 1 Then
y = y - 1
End If
'Check cells above if x <> 1
ElseIf x <> 1 Then
If .Cells(x - 1, y) = mySnake + 1 Then
x = x - 1
End If
End If
End If
Next mySnake
End With
End Sub
I have a matrix in an Excel sheet. In the first column are names of computers and in the other rows, I have users who are using it. For each computer there could be one associated user or two users and so on.
I wish to create a matrix of computers in the column and the all the users in the row and have VBA code to search the sheet, and if the user uses that computer, the output should be yes, else no.
Main Sheet
Computer A Dev Priya Rakesh Joseph
Computer B Rakesh Joseph
Computer C John Nisha Dev
Output Sheet
Computers Dev Priya Rakesh Joseph John Nisha
Computer A Y Y Y Y N N
Computer B N N Y Y N N
Computer C Y N N N Y Y
Rename sheet to 'Main' and copy data to it start from range A1.
Beware blank cell because I check end of row and column by check cell is "".
Rename other sheet to 'Output'.
Copy my code then run.
Note: Output sheet will clear all the time you run this macro.
Sub createMatrix()
Dim i As Long
Dim j As Long
Dim k As Long
Dim rngFind As Range
' Clear all contents in sheets output
Sheets("Output").Activate
Sheets("Output").Cells.ClearContents
i = 0
j = 1
k = 1
Do While Sheets("Main").Range("A1").Offset(i).Value <> ""
' Insert computer name to output sheet
Sheets("Output").Range("A2").Offset(i).Value = Sheets("Main").Range("A1").Offset(i).Value
Do While Sheets("Main").Range("A1").Offset(i, j).Value <> ""
' Check name is exists?
Set rngFind = Rows("1:1").Find(what:=Sheets("Main").Range("A1").Offset(i, j).Value, LookAt:=xlWhole)
If rngFind Is Nothing Then
' If not exists paste new name
Sheets("Output").Range("A1").Offset(0, k).Value = Sheets("Main").Range("A1").Offset(i, j).Value
' Mark use as 'Y'
Sheets("Output").Range("A1").Offset(i + 1, k).Value = "Y"
k = k + 1
Else
' Mark use as 'Y'
rngFind.Offset(i + 1).Value = "Y"
End If
j = j + 1
Loop
i = i + 1
j = 1
Loop
' This loop for Mark 'N'
i = 0
j = 1
Do While Sheets("Output").Range("A2").Offset(i).Value <> ""
Do While Sheets("Output").Range("A1").Offset(0, j).Value <> ""
' If found blank cell Mark 'N'
If Sheets("Output").Range("A2").Offset(i, j).Value = "" Then
Sheets("Output").Range("A2").Offset(i, j).Value = "N"
End If
j = j + 1
Loop
i = i + 1
j = 1
Loop
End Sub
Sample main sheet and output
This version creates a new sheet
Option Explicit
Public Sub TheMatrixReloaded() 'There is no spoon
Const FR As Long = 1: Const FC As Long = 2
Dim ws1 As Worksheet, ws2 As Worksheet, lr As Long, ur As Range
Dim ud As Object, cel As Range, i As Long
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
With ws1.UsedRange
lr = ws1.Cells(.Rows.Count + .Row + 1, FC - 1).End(xlUp).Row
Set ur = ws1.Range(ws1.Cells(FR + 1, FC), ws1.Cells(lr, .Columns.Count + .Column - 1))
End With
Set ud = CreateObject("Scripting.Dictionary")
Application.ScreenUpdating = False
Set ws2 = ThisWorkbook.Worksheets.Add(After:=ws1)
ws1.Range(ws1.Cells(FR, FC - 1), ws1.Cells(lr, FC - 1)).Copy ws2.Cells(FR, FC - 1)
For Each cel In ur
With cel
If Len(.Value2) > 0 Then
If Not ud.Exists(.Value2) Then
ud.Add .Value2, FC + i
ws2.Cells(FR, FC + i).Value2 = .Value2
ws2.Cells(.Row, FC + i).Value2 = "Y": i = i + 1
Else
ws2.Cells(.Row, ud(.Value2)).Value2 = "Y"
End If
End If
End With
Next
With ws2.UsedRange
Set ur = ws2.Range(ws2.Cells(FR + 1, FC), ws2.Cells(.Rows.Count, .Columns.Count))
Set ur = ur.SpecialCells(xlCellTypeBlanks)
End With
ur.Value2 = "N": ur.Font.Color = RGB(177, 177, 177)
ws2.Columns(1).AutoFit: ws2.UsedRange.HorizontalAlignment = xlCenter
ws2.Rows(2).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromRightOrBelow
Application.ScreenUpdating = True
End Sub
So new to coding completely. here is question :
How do I make a code that finds a multiple of a number within a set.
Ex. I have a set of number: I want to order the number beginning with the first number with every pair that is 14 a part. I was able to figure out how to do this (See code below) But now I want to do another code looking for multiples of 14 so.. It would look at x, and then find (x*14), (x*(2*14)), etc.. Any help would be appreciated
Column A Column B
459
452
426
485
425
Sub GetPairs()
Dim x, z As Single
Dim lastrow, pasterow As Single
Dim testMass, nomMass As Single
lastrow = Worksheets(1).Cells(Rows.Count, 2).End(xlUp).Row
pasterow = 2
For x = 2 To lastrow
nomMass = Cells(x, 2).Value
testMass = Cells(x, 2) + 14
o
r z = 2 To lastrow
If Cells(z, 2).Value = testMass Then
Cells(pasterow, 7).Value = nomMass
Cells(pasterow, 8).Value = Cells(z, 2).Value
pasterow = pasterow + 1
End If
Next z
Next x
End Sub
Actually, it should be that simple.
multiple = Cells(x*14, 2)
I think that should do what you want.
Yes That worked perfectly.
Here is the final code I came up with :
Sub GetPairs()
``Dim x As Single, z As Single
Dim lastRow, pasterow As Single
Dim testMass, nomMass As Single
`` Dim lastValue As Long
` Dim colCounter As Long
``Dim lookUpRange As Range
`lastRow = Worksheets(1).Cells(Rows.Count, 2).End(xlUp).Row
`lastValue = Worksheets(1).Cells(Rows.Count, 2).End(xlUp).Value
`Set lookUpRange = Worksheets(1).Range("B2:B" & lastRow)
``pasterow = 2
`For x = 2 To lastRow
nomMass = Cells(x, 2).Value ' base value
colCounter = 3
For z = Round((nomMass + 14), 0) To Round((lastValue + 14), 0) Step 14
If Found(lookUpRange, z) Then
'found
Worksheets(1).Cells(x, colCounter) = z
colCounter = colCounter + 1
End If
Next z
Next x
End Sub
Private Function Found(rng As Range, valueToFind) As Boolean
On Error GoTo errHandler
Dim v
v = WorksheetFunction.VLookup(valueToFind, rng, 1, 0)
Found = True