I have 2 excel sheets one is mapping and other is soneri. I want to increment the values of Column D in soneri sheet which was get by lookup function. What is the mistake in my code?
soneri sheet
mappingsheet
Outcome
Column D
Only first 2 rows are correct of my outcome else are wrong.
Expected Outcome
Below is my code
"WORKING CODE EDITED"
Sub ButtonClick()
Dim soneriWs As Worksheet, mappingWs As Worksheet
Dim sonerilastrow As Long, mappinglastrow As Long, i As Long
Dim datarange As Range, assetrange As Range, b As Range
Dim entry As Variant
Set soneriWs = ThisWorkbook.Worksheets("Soneri")
Set mappingWs = ThisWorkbook.Worksheets("Mapping")
sonerilastrow = soneriWs.Range("I" & soneriWs.Rows.Count).End(xlUp).Row
mappinglastrow = mappingWs.Range("A" & mappingWs.Rows.Count).End(xlUp).Row
Set datarange = mappingWs.Range("A2:B" & mappinglastrow)
Set assetrange = soneriWs.Range("I2:I" & sonerilastrow)
i = 0
For Each entry In assetrange
Set b = entry.Offset(, -5)
b = Application.WorksheetFunction.VLookup(entry, datarange, 2, False)
If entry = entry.Offset(-1) Then
i = i + 1
b = Left(b, Len(b) - 1) & (Right(b, 1) + i)
Else
i = 0
End If
Next entry
End Sub
Rows.Count returns that number of rows for the active sheet. Try changing these two lines:
sonerilastrow = soneriWs.Range("I" & Rows.Count).End(xlUp).Row
mappinglastrow = mappingWs.Range("A" & Rows.Count).End(xlUp).Row
To this:
sonerilastrow = soneriWs.Range("I" & soneriWs.Rows.Count).End(xlUp).Row
mappinglastrow = mappingWs.Range("A" & mappingWs.Rows.Count).End(xlUp).Row
Also remember to clear any errors that might occur, otherwise you can run into trouble. Insert this before the Sub returns:
If Err <> 0 Then Err.Clear
I see you removed your "on error" statement.
I would also recommend that you force variable decalarations, as I can see you use undeclared variables, which will also get you into trouble sooner or later. Insert this as the first line in all modules:
Option Explicit
EDIT:
Please post test data "as text" next time to help people help you.
Here is a solution.
I uncommented your if statement, as it seem to not update the first record.
Sub ButtonClick()
Dim soneriWs As Worksheet, mappingWs As Worksheet
Dim sonerilastrow As Long, mappinglastrow As Long, x As Long, b As String, c As String
Dim Dct As Object
Dim Cnt As Long
Dim CntTxt As String
Dim PreTxt As String
Dim Idx As Long
Dim datarange As Range
Set soneriWs = ThisWorkbook.Worksheets("Soneri")
Set mappingWs = ThisWorkbook.Worksheets("Mapping")
sonerilastrow = soneriWs.UsedRange.Rows.Count
mappinglastrow = mappingWs.UsedRange.Rows.Count
Set Dct = CreateObject("Scripting.Dictionary")
Set datarange = mappingWs.Range("A2:B" & mappinglastrow)
For x = 2 To sonerilastrow
b = Application.WorksheetFunction.VLookup(soneriWs.Range("I" & x).Value, datarange, 2, False)
Idx = InStr(b, "-")
PreTxt = Left(b, Idx)
CntTxt = Mid(b, Idx + 1)
If Dct.Exists(b) Then
Cnt = Dct(b) + 1
Else
Cnt = Val(CntTxt)
End If
Dct(b) = Cnt
'If x > 2 Then
c = PreTxt & Format(Cnt, "0000")
' Use this instead, if you want to preserve the number of characters
'c = PreTxt & Format(Cnt, String(Len(CntTxt), "0"))
soneriWs.Range("D" & x).Value = c
'End If
Next x
End Sub
If you are new to VBA I recommend that you learn how to use the Scripting.Dictionary.
Your loop is only made for a single match of the Asset class.
There are a few problems here, but the if x > 2 approach would really only work if there was only one counter. Then we could substitute + 1 with something like + x - 2 (since we start at 3 for this part of the code).
But what you need is a counter that resets each time there is a new Asset class.
n = 1
For x = 2 To sonerilastrow
b = Application.WorksheetFunction.VLookup( _
soneriWs.Range("I" & x).Value, datarange, 2, False)
soneriWs.Range("D" & x).Value = b
If x > 2 Then
If Not Left(b, 7) = Left(soneriWs.Range("D" & x -1).Value, 7) then
n = 1
else
c = Left(b, 7) & Format(Val(Right(b, 4)) + n, "-0000")
soneriWs.Range("D" & x).Value = c
n = n + 1
End if
End If
Next x
Another way of writing it would be
Dim soneriWs As Worksheet, mappingWs As Worksheet
Dim sonerilastrow As Long, mappinglastrow As Long, i As Long
Dim datarange As Range, assetrange As Range, b As Range
Dim entry As Variant
Set soneriWs = ThisWorkbook.Worksheets("Soneri")
Set mappingWs = ThisWorkbook.Worksheets("Mapping")
sonerilastrow = soneriWs.Range("I" & soneriWs.Rows.Count).End(xlUp).Row
mappinglastrow = mappingWs.Range("A" & mappingWs.Rows.Count).End(xlUp).Row
Set datarange = mappingWs.Range("A2:B" & mappinglastrow)
Set assetrange = soneriWs.Range("I2:I" & sonerilastrow)
i = 0
For Each entry In assetrange
Set b = entry.Offset(, -5)
b = Application.WorksheetFunction.VLookup(entry, datarange, 2, False)
If entry = entry.Offset(-1) Then
i = i + 1
b = Left(b, Len(b) - 1) & (Right(b, 1) + i)
Else
i = 0
End If
Next entry
But it's using much the same approach.
These however expect the data to be sorted on the "I" column, since the counter will reset if there is another asset in between.
If you want it to work even when not sorted, you could use something like countIf, like so: (Replacing the loop)
Set assetrange = soneriWs.Range("I2:I" & sonerilastrow)
assetrange.Offset(, -5).Clear
For Each entry In assetrange
Set b = entry.Offset(, -5)
b = Application.WorksheetFunction.VLookup(entry, datarange, 2, False)
i = Application.WorksheetFunction.CountIf(assetrange.Offset(, -5), Left(b, 5) & "*")
b = Left(b, Len(b) - 1) & (Right(b, 1) + i - 1)
Next entry
Related
I have a table in an active worksheet.
I am trying to:
Scan Columns(A:M) of Row 6 to see if all cells are empty
If yes, then scan Columns (N:R) of Row 6 to see if all cells are empty
If 2. is false, then copy above row's Columns (A:I) in Row 6
Repeat 1-3 but on Row 7
This process should repeat until the rows of the table end.
I would like to incorporate ActiveSheet.ListObjects(1).Name or something similar to duplicate the sheet without having to tweak the code.
How I can make this as efficient and as risk free as possible? My code works but it's really too much.
Sub CopyPasteRow()
Dim lr As Long
Dim x As Long
Dim y As Long
Dim a As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
a = 0
For x = 6 To lr
For y = 1 To 13
If Not IsEmpty(Cells(x, y)) Then
a = a + 1
End If
Next y
If a = 0 Then
For y = 14 To 18
If Not IsEmpty(Cells(x, y)) Then
a = a + 1
End If
Next y
Else
a = 0
End If
If a <> 0 Then
For y = 1 To 13
Cells(x, y).Value = Cells(x - 1, y).Value
Next y
End If
a = 0
Next x
End Sub
This is the final code based on #CHill60 code. It got me 99% where I wanted.
Sub CopyPasteRow()
Dim lr As Long
Dim x As Long
Dim a As Long
Dim r As Range, r2 As Range, r3 As Range
lr = Cells(Rows.Count, 1).End(xlUp).Row
For x = 6 To lr
'check columns A to M for this row are empty
Set r = ActiveSheet.Range("A" & CStr(x) & ":M" & CStr(x))
'check columns N to R for this row are empty
Set r2 = ActiveSheet.Range("N" & CStr(x) & ":R" & CStr(x))
If WorksheetFunction.CountA(r) = 0 And WorksheetFunction.CountA(r2) <> 0 Then
'copy the data into columns A to M
Set r3 = ActiveSheet.Range("A" & CStr(x) & ":I" & CStr(x))
r3.Value = r3.Offset(-1, 0).Value
End If
Next x
End Sub
Instead of looking at individual cells, look at Ranges instead. Consider this snippet of code
Sub demo()
Dim x As Long
For x = 6 To 8
Dim r As Range
Set r = Sheets(1).Range("A" & CStr(x) & ":M" & CStr(x))
Debug.Print r.Address, MyIsEmpty(r)
Next x
End Sub
I have a function for checking for empty ranges
Public Function MyIsEmpty(rng As Range) As Boolean
MyIsEmpty = WorksheetFunction.CountA(rng) = 0
End Function
I use this because the cell might "look" empty, but actually contain a formula.
Note I've explicitly said which sheet I want the Cells from - users have a habit of clicking places other than where you think they should be! :laugh:
Edit after OP comment:
E.g. your function might look like this
Sub CopyPasteRow()
Dim lr As Long
Dim x As Long
Dim a As Long
Dim r As Range, r2 As Range
lr = Cells(Rows.Count, 1).End(xlUp).Row
For x = 6 To lr
a = 0
'check columns A to M for this row are empty
Set r = Sheets(1).Range("A" & CStr(x) & ":M" & CStr(x))
If Not MyIsEmpty(r) Then
a = a + 1
End If
If a = 0 Then
'check columns N to R for this row are empty
Set r2 = Sheets(1).Range("N" & CStr(x) & ":R" & CStr(x))
If Not MyIsEmpty(r2) Then
a = a + 1
End If
Else
a = 0
End If
If a <> 0 Then
'copy the data into columns A to M
'You might have to adjust the ranges here
r.Value = r2.Value
End If
Next x
End Sub
where you have a source range and a target range - you appear to be putting the values in the previous row so my value of r is probably wrong in this example - you could use r.Offset(-1,0).Value = r2.Value
I'm also not sure what you are trying to do with the variable a If that is meant to be a "flag" then consider using a Boolean instead - it only has the values True or False
I am trying to work out the looping on my script but have found it difficult to figure out. I am using this script to find matching data from different sources and reference them together. I would use the built-in functions in excel but it doesn't care about finding the same data more than once.
Read the titles of all the spreadsheets in the book. #Works
Make an array with those titles #Works
Filter out the "current" sheet #Works
Reference each cell in column A on "current" sheet against all the cells on all the pages in column H #Works
If it matches one, take the data from the page it was found on and the data in column G then set that as the value on "current" page in column E #Works
Make the next page in the main sheet array the "current" page and do it all over again #Doesn't Work
I didn't think this would be as complicated as it is, and maybe I'm not helping by not using functions. Got any idea on how to advance inspectSheet correctly?
Sub listsheets()
Dim ws As Worksheet
Dim i As Integer
Dim x As Integer
Dim y As Integer
Dim sheetArray() As Variant
x = 0
y = 0
i = 0
For Each ws In Worksheets
ReDim Preserve sheetArray(i)
sheetArray(i) = ws.Name
i = i + 1
Next ws
Do Until i = 1
i = i - 1
inspectSheet = sheetArray(x)
column = Sheets(inspectSheet).Cells(Rows.Count, "A").End(xlUp).Row
matchArray = Filter(sheetArray, inspectSheet, False, vbTextCompare)
HOLDER = Join(matchArray)
matchSheet = matchArray(y)
Do Until column = 1
currentCell = Sheets(inspectSheet).Cells(column, 1).Value
checkListLength = Sheets(matchSheet).Cells(Rows.Count, "H").End(xlUp).Row
Do Until checkListLength = 1
matchCell = Sheets(matchSheet).Cells(checkListLength, 8).Value
Debug.Print "Checking: " + currentCell + " on " + inspectSheet + " against " + matchCell + " from page " + matchSheet
If currentCell = matchCell Then
Sheets(inspectSheet).Cells(column, 5).Value = matchSheet + " on " + Sheets(matchSheet).Cells(checkListLength, 7).Value
End If
checkListLength = checkListLength - 1
Loop
column = column - 1
Loop
y = y + 1
Loop
x = x + 1
End Sub
I see you already answered your own question, but here's a slightly different approach with fewer counters to track:
Sub listsheets()
Dim wsMatch As Worksheet, wsInspect As Worksheet
Dim currVal
Dim cInspect As Range, cMatch As Range, rngMatch As Range, rngInspect As Range
For Each wsInspect In ThisWorkbook.Worksheets
Set rngInspect = wsInspect.Range("A1:A" & wsInspect.Cells(Rows.Count, "A").End(xlUp).Row)
For Each wsMatch In ThisWorkbook.Worksheets
If wsMatch.Name <> wsInspect.Name Then 'filter out same-name pairs...
Set rngMatch = wsMatch.Range("H1:H" & wsMatch.Cells(Rows.Count, "H").End(xlUp).Row)
For Each cInspect In rngInspect.Cells
currVal = cInspect.Value
For Each cMatch In rngMatch.Cells
If cMatch.Value = currVal Then
cInspect.EntireRow.Columns("E").Value = _
wsMatch.Name & " on " & cMatch.Offset(0, -1).Value
End If
Next cMatch
Next cInspect
End If 'checking these sheets
Next wsMatch
Next wsInspect
End Sub
I got it, I was not resetting my counter variables and needed one more external loop to advance. The finished code is:
Sub listsheets()
Dim ws As Worksheet
Dim i As Integer
Dim x As Integer
Dim y As Integer
Dim limit As Integer
Dim sheetArray() As Variant
x = 0
y = 0
i = 0
For Each ws In Worksheets
ReDim Preserve sheetArray(i)
sheetArray(i) = ws.Name
i = i + 1
Next ws
limit = UBound(sheetArray)
Do Until x = limit
Do Until i = 1
i = i - 1
inspectSheet = sheetArray(x)
Column = Sheets(inspectSheet).Cells(Rows.Count, "A").End(xlUp).Row
matchArray = Filter(sheetArray, inspectSheet, False, vbTextCompare)
HOLDER = Join(matchArray)
matchSheet = matchArray(y)
Do Until Column = 1
currentCell = Sheets(inspectSheet).Cells(Column, 1).Value
checkListLength = Sheets(matchSheet).Cells(Rows.Count, "H").End(xlUp).Row
Do Until checkListLength = 1
matchCell = Sheets(matchSheet).Cells(checkListLength, 8).Value
Debug.Print "Checking: " + currentCell + " on " + inspectSheet + " against " + matchCell + " from page " + matchSheet
If currentCell = matchCell Then
Sheets(inspectSheet).Cells(Column, 5).Value = matchSheet + " on " + Sheets(matchSheet).Cells(checkListLength, 7).Value
End If
checkListLength = checkListLength - 1
Loop
Column = Column - 1
Loop
y = y + 1
Loop
i = UBound(sheetArray)
y = 0
x = x + 1
Loop
End Sub
I have a bubble sort that only works with the first element.
This is solved by reevaluating my array elements and placing them accordingly, which happens if I run the whole thing time and time again.
I'd like to add a recursive loop that's set to break when the sort is done.
I tried adding a function, but I'm not solid enough on my syntax to combine it with my sub. What is a basic recursion loop for this code? Function not expressly required, just something that will let me recall my sub.
Private Sub SortEverything_Click()
Dim everything() As Range
Dim check As Range
Dim count As Range
Dim sorting As Range
Dim holder As Range
Dim middleman As Range
Dim firstman As Range
Dim Temp1 As String
Dim Temp2 As String
Dim lr As Long
Dim x As Long
Dim y As Long
Dim z As Long
Dim q As Long
Dim everyrow As Long
Dim everycol As Long
Dim firstrow As Long
Dim firstcol As Long
y = 0
z = 0
q = 0
With ThisWorkbook.Sheets("Names and Vendors")
lr = .Cells(.Rows.count, "B").End(xlUp).Row
'Counts number of RMs to size the "everything" array
For z = 2 To lr
Set count = .Range("B" & z)
If IsEmpty(count) = False Then
count.Select
q = q + 1
End If
Next z
ReDim everything(q - 1) As Range 'Resizes array
'Loops all RM info into array by each distinct range
For x = 2 To lr
Set check = .Range("A" & x & ":H" & x)
'ensures subcomponents are added to range
If IsEmpty(.Range("B" & 1 + x)) = True Then
Do While IsEmpty(.Range("B" & 1 + x)) = True And x < lr
Set check = Union(check, .Range("A" & 1 + x & ":H" & 1 + x))
check.Select
x = x + 1
Loop
End If
Set everything(y) = check
y = y + 1
check.Select
Next x
'This For has been commented out so that it doesn't run more than once
'For y = 0 To q - 1
'sorting allows us to copy/paste into a helper range line-by-line as the program loops
'firstman is the helper range. firstrow and firstcol return the dimensions of the everything(y) so that we can resize things
Set sorting = everything(0)
Set firstman = .Range("B20")
Set firstman = firstman.Resize(sorting.Rows.count, sorting.Columns.count)
firstman.Value = sorting.Value
firstrow = firstman.Rows.count
firstcol = firstman.Columns.count
'Returns the name of the RM listed to compare to the one below it
sorting.Offset(0, 1).Select
ActiveCell.Select
Temp1 = "" & ActiveCell.Value
For x = 1 To q - 1
'Checks whether a selected component has subcomponents and identifies its dimensions
sorting.Select
Set holder = everything(x)
holder.Offset(0, 1).Select
everyrow = Selection.Rows.count
everycol = Selection.Columns.count
'Returns the name of the material being compared to the referenced material in everything(y)
ActiveCell.Select
Temp2 = "" & ActiveCell.Value
If Temp2 > Temp1 Then 'If the RM we're on comes alphabetically after the name of the one we're checking against, then
If everyrow > 1 Then 'Handles if everything(x) has subcomponents
'Resize the other helper range to be the same as the range with subcomponents and paste the values into it
Set middleman = .Range("A1").Offset(0, everything(x).Columns.count)
Set middleman = middleman.Resize(everyrow, everycol)
middleman.Select
middleman.Value = holder.Value
'Resize the range we're pasting into in the master table so it can take the new range, then paste
Set sorting = sorting.Resize(everyrow, everycol)
sorting.Select
sorting.Value = holder.Value
'Resize the holder column to the same size as everything(y).
'Then paste everything(y) into the space BELOW the one we've just shifted upwards
Set holder = holder.Resize(firstrow, firstcol)
Set holder = holder.Offset(everyrow - 1, 0)
holder.Select
holder.Value = firstman.Value
Set sorting = sorting.Offset(everyrow, 0)
Else
Set middleman = .Range("A1").Offset(0, everything(x).Columns.count)
Set middleman = middleman.Resize(firstrow, firstcol)
middleman.Select
middleman.Value = holder.Value
Set sorting = sorting.Resize(everyrow, everycol)
sorting.Select
sorting.Value = holder.Value
Set holder = holder.Resize(firstrow, firstcol)
'Set firstman = firstman.Resize(everyrow, everycol)
holder.Select
holder = firstman.Value
Set sorting = sorting.Offset(1, 0)
End If
End If
Next x
'Next y
'This is where my inexperience shows. The recursion should go here, but I'm not sure how to do so.
'PopulateArray (everything)
End With
End Sub
Public Function PopulateArray(myArray()) As Variant
Dim myArray() As Range
Dim check As Range
Dim count As Range
Dim sorting As Range
Dim holder As Range
Dim middleman As Range
Dim firstman As Range
Dim Temp1 As String
Dim Temp2 As String
Dim lr As Long
Dim x As Long
Dim y As Long
Dim z As Long
Dim q As Long
y = 0
z = 0
q = 0
With ThisWorkbook.Sheets("Names and Vendors")
lr = .Cells(.Rows.count, "B").End(xlUp).Row
'Counts number of RMs to size the "myArray" array
For z = 2 To lr
Set count = .Range("B" & z)
If IsEmpty(count) = False Then
count.Select
q = q + 1
End If
Next z
ReDim myArray(q - 1) As Range 'Resizes array
'Loops all RM info into array by each distinct range
For x = 2 To lr
Set check = .Range("A" & x & ":H" & x)
'ensures subcomponents are added to range
If IsEmpty(.Range("B" & 1 + x)) = True Then
Do While IsEmpty(.Range("B" & 1 + x)) = True And x < lr
Set check = Union(check, .Range("A" & 1 + x & ":H" & 1 + x))
check.Select
x = x + 1
Loop
End If
Set myArray(y) = check
y = y + 1
check.Select
Next x
End With
End Function
Found out what I needed to do. Put the whole thing under a Do loop and then added the following lines to it:
'checking to see if array is completely alphabetized
For Each cell In .Range("B2:B" & lr)
'Returns first check value
If IsEmpty(cell) = False Then
cell.Select
check1 = "" & cell.Value
x = cell.Row
.Range("A14").Value = check1
'Returns next check value
For z = x + 1 To lr
Set checking = .Range("B" & z)
If IsEmpty(checking) = False Then
checking.Select
check2 = "" & .Range("B" & z).Value
.Range("A15").Value = check2
Exit For
End If
Next z
Else
End If
If check2 > check1 Then
Exit For
End If
Next cell
'If the last two values are sorted, then the whole thing is sorted and we can stop the recursion
If check2 < check1 Or check1 = check2 Then
Exit Do
End If
Been trying to solve this problem.
I have this sample data to get the rows who are in between Date From and Date to:
Sheet1
This sheet contains Date From: and Date To: cells that will automatically shows the result below
Here's my Sheet2 where the data extracted from
Here's my current VBA code.
Sub FinalData()
Dim lastrow As Long
Dim count As Integer
Dim p As Integer
Dim x As Integer
lastrow = Sheets("Sheet2").Cells(rows.count, 1).End(xlUp).row
Sheets("Sheet1").Range("A5:C1000").ClearContents
count = 0
p = 5
For x = 2 To lastrow
If Sheets("Sheet2").Range("C2:C100") >= Sheets("Sheet1").Cells(1, 2) AND Sheets("Sheet2").Range("C2:C100") <= Sheets("Sheet1").Cells(2, 2) Then
Sheets("Sheet1").Cells(p, 1) = Sheets("Sheet2").Cells(x, 1)
Sheets("Sheet1").Cells(p, 2) = Sheets("Sheet2").Cells(x, 2)
Sheets("Sheet1").Cells(p, 3) = Sheets("Sheet2").Cells(x, 3)
p = p + 1
count = count + 1
End If
Next x
MsgBox " The number of data found for this Area is " & " " & count
End Sub
Is there something wrong with my code? This code works fine from my last project but when I try to use this to get the rows for Date. I think the problem is on the conditional statement that I made.
The problem is you're trying to compare a range of cells with two single cells.
Untested:
Sub FinalData()
Dim lastrow As Long
Dim count As Long
Dim p As Long
Dim x As Long, dt
Dim wsReport As Worksheet, wsData As Worksheet
Set wsReport = ThisWorkbook.Sheets("Sheet1")
Set wsData = ThisWorkbook.Sheets("Sheet2")
lastrow = wsData.Cells(Rows.count, 1).End(xlUp).Row
wsReport.Range("A5:C1000").ClearContents
count = 0
p = 5
For x = 2 To lastrow
dt = wsData.Cells(x, "C")
If dt >= wsReport.Cells(1, 2) And dt <= wsReport.Cells(2, 2) Then
With wsReport
.Cells(p, 1) = wsData.Cells(x, 1)
.Cells(p, 2) = wsData.Cells(x, 2)
.Cells(p, 3) = wsData.Cells(x, 3)
End With
p = p + 1
count = count + 1
End If
Next x
MsgBox " The number of data found for this Area is " & " " & count
End Sub
I generated radio buttons with the help of the answer to How to set an automatically generated radio button to true in VBA?.
My requirement is to set the automatically generated Option button to 'True' when there is a value x in another sheet.
Figure 1: The source to check the value.
Figure 2: The sheet to which the Mark x should be reflected as True.
The radio buttons that are generated are as Indexed as OB2_2 for the option button in 2 row and 2 column.
Here is the code
Private Sub AddOptionButtons(ByRef TargetRange As Range)
Dim m As Variant
m = Sheets("ALLO").Range("D23").Value + 1
Sheets("Final").Range("A2:A" & m).Copy Destination:=Sheets("Int_Result").Range("A2:A" & m)
Dim oCell As Range
For Each oCell In TargetRange
oCell.RowHeight = 20
oCell.ColumnWidth = 6
Dim oOptionButton As OLEObject
Set oOptionButton = TargetRange.Worksheet.OLEObjects.Add(ClassType:="Forms.OptionButton.1", Left:=oCell.Left + 1, Top:=oCell.Top + 1, Width:=15, Height:=18)
oOptionButton.Name = "OB" & oCell.row & "_" & oCell.Column
oOptionButton.Object.GroupName = "grp" & oCell.Top
Next
Call OB2_Click(oCell)
End Sub
Sub OB2_Click(oCell)
Dim col, ro, m As Variant
Dim Shap As Shape
m = Sheets("ALLO").Range("D23").Value + 1
For Each Shap In Sheets("Int_Result").Shapes
For ro = 2 To m Step 1
For col = 1 To 13 Step 1
If Sheets("Final").Cells(ro, col).Value = "" Then
Sheets("Int_Result").Shapes(ro, col).ControlFormat.Value = False
Else
Sheets("Int_Result").Shapes(ro, col).ControlFormat.Value = True
End If
Next col
Next ro
Next Shap
End Sub
I get
"Object variable or With block variable not set" or "Wrong number of arguments or Invalid Property assignment".
on this line
Sheets("Int_Result").Shapes(ro, col).ControlFormat.Value = False
How do I access the automatically generated radio buttons?
You need to use
Sheets("Int_Result").OLEObjects("OB2_2").Object.Value = True
Set loop not for shapes, but normal to last row and last column.
So for example:
Dim oCell As Range
Dim LastCell As Range
For Each oCell In TargetRange
oCell.RowHeight = 20
oCell.ColumnWidth = 6
Dim oOptionButton As OLEObject
Set oOptionButton = TargetRange.Worksheet.OLEObjects.Add(ClassType:="Forms.OptionButton.1", Left:=oCell.Left + 1, Top:=oCell.Top + 1, Width:=15, Height:=18)
oOptionButton.Name = "OB" & oCell.Row & "_" & oCell.Column
oOptionButton.Object.GroupName = "grp" & oCell.Top
Set LastCell = oCell
Next
Call OB2_Click(LastCell)
Sub OB2_Click(oCell as Range)
Dim col As Long, ro As Long
dim m as long, k as long
col = oCell.Column
ro = oCell.Row
For m = 2 to ro
For k = 2 to col
If Sheets("Final").Cells(m, k).Value = "" Then
Sheets("Int_Result").OLEObjects("OB" & m & "_" & k).Object.Value = False
Else
Sheets("Int_Result").OLEObjects("OB" & m & "_" & k).Object.Value = True
End If
Next k
Next m
End sub