I got an excel file with a data source sheet. To be able to parse the data at the next step I need to add 1 to every value and get it into a new sheet. The thing is, that there are multiple values per cell, each separated by comma, and this number is not static. Adding the +1 at a later point is sadly not an option so I need to do this in excel.
Source sheet Prepared data sheet
| MyValues | | MyValues + 1 |
|------------| |--------------|
| 0,1,2,3 | | 1,2,3,4 |
| 3 | -----> | 4 |
| 2,4,6 | | 3,5,7 |
| 1 | | 2 |
Here's helper column based solution. I have assumed data starts from cell A2 and concatenation formula in cell B2. I have considered case of 15 maximum values.
In cell C2, following formula shall be put:
=IFERROR((TRIM(MID(SUBSTITUTE(","&$A2,",",REPT(" ",99)),COLUMNS($A$1:A1)*99,99))/1)+1,"")
This shall be copied across (till column Q) and down (till last row of your data).
Then apply concatenation formula as below in cell B2:
=SUBSTITUTE(TRIM(CONCATENATE(C2," ",D2," ",E2," ",F2," ",G2," ",H2," ",I2," ",J2," ",K2," ",L2," ",M2," ",N2," ",O2," ",P2," ",Q2))," ",",")
shall work for Excel Version 2007 or higher.
Here is one way doing this (assuming Excel 2016 with TEXTJOIN()):
Formula in B1:
=IFERROR(TRIM(MID(SUBSTITUTE($A1,",",REPT(" ",LEN($A1))),(COLUMN()-2)*LEN($A1)+1,LEN($A1)))+1,"")
Drag down and sideways (could be 15 columns if need be)
Formula in G1:
=TEXTJOIN(",",TRUE,B1:E1)
Drag down
You don't need a VBA solution but in your case a UDF could also be a nice way to do this, for example like so:
Function AddVal(RNG As Range, VAL As Double) As String
Dim ARR1() As String, ARR2() As String, X As Double
If RNG.Cells.Count = 1 Then
ARR = Split(RNG.Value, ",")
For X = LBound(ARR) To UBound(ARR)
ReDim Preserve ARR2(X)
ARR2(X) = ARR(X) + VAL
Next X
If IsEmpty(ARR2) Then
AddVal = "No hits"
Else
AddVal = Join(ARR2, ",")
End If
Else
AddVal = "No valid range"
End If
End Function
Call through =AddVal(A1;1)
You can change the 1 for another number if you want to add more than just 1.
I try to create a VBA code (i know that VBA is not tagged) to fulfill this task.
Option Explicit
Sub test()
Dim LastRow As Long, i As Long, Count As Long, j As Long
Dim str As Variant, strNew As String
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 1 To LastRow
Count = Len(.Range("A" & i).Value) - Len(Replace(.Range("A" & i).Value, ",", ""))
str = Split(.Range("A" & i).Value, ",")
If Count > 0 Then
For j = 0 To Count
str(j) = str(j) + 1
If .Range("B" & i).Value = "" Then
.Range("B" & i).Value = str(j)
Else
.Range("B" & i).Value = .Range("B" & i).Value & "," & str(j)
End If
Next j
Else
.Range("B" & i).Value = .Range("A" & i).Value + 1
End If
Next i
End With
End Sub
Results:
Related
So, I haven't figured out how to do this.
Basically, I want something like this:
P1 P2 P3 TOTAL SCORE
-- -- -- P1 P2 P3
21 / 13 1 2 0
/ 17 10
6 7 /
So, the three columns must compare to one-another (the "/" means that the player didn't play that game, but it doesn't have to be printed), the greatest among the three gets a +1 value in the TOTAL SCORE tab.
Plus, is there any easier way to do this than comparing one cell to another cell? I mean, is there a possibility to drag and mark all cells on all of the three columns and make sure that they only compare the cells in the three columns IN THE SAME ROW?
Let us assume that the data appears as in the picture in Sheet1 (Don't change the structure):
Open an Excel
Press ALT & F11 to open Visual Editor
Add a module from > Insert (in the Upper toolbar) - Module ( third option)
Paste the below codes & execute Sub Evaluation() (press F5 when your cursor is in Sub Evaluation)
To store lastrow in order to continue from the next record i use sheet2 range A1
Try:
Option Explicit
Public Sub Process_Data(ByVal I_Value As Long)
Dim LastRow As Long
Dim i As Long
Dim CA As Integer
Dim CB As Integer
Dim CC As Integer
With Sheet1
LastRow = .Range("A" & Rows.Count).End(xlUp).Row
For i = I_Value To LastRow '<= Lets say that the first score is at sheet1 column A row 3.LastRow represent the row of the last data in column A
CA = 0
CB = 0 '<= Every time that i change value we zero our variables to get the new value
CC = 0
If .Range("A" & i).Value = "/" Then '<= Check if there is a number or "/".if there is "/" we zero variable
CA = 0
Else
CA = .Range("A" & i).Value
End If
If .Range("B" & i).Value = "/" Then
CB = 0
Else
CB = .Range("B" & i).Value
End If
If .Range("C" & i).Value = "/" Then
CC = 0
Else
CC = .Range("C" & i).Value
End If
If CA > CB And CA > CC Then ' <= Check which number is bigger
.Range("E3").Value = .Range("E3").Value + 1 '<= At one point to each category
ElseIf CB > CA And CB > CC Then
.Range("F3").Value = .Range("F3").Value + 1
ElseIf CC > CA And CC > CB Then
.Range("G3").Value = .Range("G3").Value + 1
End If
Next i
End With
End Sub
Sub Evaluation()
Dim Value As Long
Dim LastRow As Long
LastRow = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
If (LastRow = 2) Or (LastRow = Sheet2.Range("A1").Value) Then '<= Check if the table has new data
Exit Sub
Else
If Sheet2.Range("A1").Value = "" Then '<=Check which value will adopt be i
Value = 3
Else
Value = Sheet2.Range("A1").Value + 1
End If
End If
Call Process_Data(I_Value:=Value)
Sheet2.Range("A1").Value = Sheet1.Range("A" & Rows.Count).End(xlUp).Row '<= Record the lastrow processed out
End Sub
Use the LARGE function to find the highest number for the individual games on the left. Then use an IF statement out to the right to check if the value of the LARGE function matches the player's game score. If it does match (TRUE), assign a value of 1. If it doesn't match (FALSE), assign a value of 0. Then SUM each player's modifiers that you've assigned with the IF function.
If ties are possible in the individual game scores, you'll also need to nest another IF function to handle that possibility.
I'm not sure how to start this code and I am not very good at VBA. Basically I have 2 columns I am interested in. One column (column E) contains cells with the word Header. I want to count those from top to bottom and in a cell 1 row to the left I need to put the current count at the beginning of the text in that cell.
ROW | column D | Column E
1 | AHU | Header
2 | random | random
3 | FCU | Header
If you don't need VBA, you could use =COUNTIF($E$2:E2,"Header")
If you are going to loop through the rows, you can use a counter like below:
Dim ct as Long
Dim i as Long
Dim iLastRow as Long
iLastRow = Range("E2", Range("E" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible).Count
For i = 2 to iLastRow
If Range("E" & i).value="Header" then
ct = ct + 1
Range("D" & i).value = ct & "-" & Range("D" & i).value
End If
Next i
lets say in column A:Row 2, I have a score of 45 and in column B, I have the amount of people that got that score. what i then want to do is on column D, output that score X amount of times. x=repitition.
in the exmaple 5 people got a score of 45 so in column D i want to insert 5 scores of 45. then I see in column A:Row2 3 people got a score of 46 then after the last 45, in column D I want to append 46 3 times.. and so on..
Could someone show me how to do this?
Here you go:
Sub test_scores_repitition()
'run with test scores sheet active
r = 1
dest_r = 1
Do While Not IsEmpty(Range("a" & r))
If IsEmpty(Range("b" & r)) Then Range("b" & r).Value = 0 'if there's no quantity listed for a score, it assumes zero
For i = 1 To Range("b" & r).Value
Range("d" & dest_r).Value = Range("a" & r).Value
dest_r = dest_r + 1
Next i
r = r + 1
Loop
End Sub
Macro answer:
Sub WriteIt()
Dim lrow As Long
Dim WriteRow As Long
Dim EachCount As Long
Dim ReadRow As Long
' find last in list of numbers
lrow = Range("A1").End(xlDown).Row
'start at 2 because of headers
WriteRow = 2
ReadRow = 2
While ReadRow <= lrow
For EachCount = 1 To Cells(ReadRow, 2)
'repeat the number of times in column B
Cells(WriteRow, 4) = Cells(ReadRow, 1)
'the number in column A
WriteRow = WriteRow + 1
Next
ReadRow = ReadRow + 1
'and move to the next row
Wend
'finish when we've written them all
End Sub
it is possible with a formula, just not really recommended as it looks auful, and would be difficult to explain. It uses a Microsoft formula to count the number of unique items in the data above, and once it counts the number it is supposed to write of the number above, it moves to the next number. The formula does not know where to stop, and will put 0 when it runs out of data.
in D2, put =A2
In D3, and copied down, put
=IF(COUNTIF($D$2:D2,OFFSET($A$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1)),0))<OFFSET($B$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1)),0),OFFSET($A$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1)),0),OFFSET($A$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1))+1,0))
I'm making an heuristic analyse and i have the fallowing problem : I want to find in column D numbers that match with column J and replace them by a "0". You can see what I'm trying to do on this image :
Problem : Column D have multiples values per cell and column J have one value per cell.
some part of the code:
Dim i,j As Integer
Dim temp As String
Dim x As Integer
Dim d As String
i = Application.CountA(Range("E:E")) + 10
'number of cell with values
j = Application.CountA(Range("J:J")) + 10
For j = 11 To j
temp = Range("J" & j).Value
For i = 11 To i
d = Range("D" & i).Value
*For x = LBound(vec) To UBound(vec)
If vec(x) = temp Then
vec(x) = 0
Range("D" & i).Value = vec(x)
End If
Next
Next
Next
*-> Here it is the problem, i cant figured out how to pass over the coma "," in column D,and store the data. I want to compare the temp with value on "d", but "d" can i have multiple numbers on the same cell, like " 3, 2, 1", and if there is any match like temp = 3, then d= "0,2,1".
English is not my native language so i hope you can understand what i want.
Thanks!
I think your almost there you just need to split up each cell and then search then recreate and replace the string in the cell. Please note I've not tested this.
Dim i,j As Integer
Dim temp As String
Dim x As Integer
Dim d As String
i = Application.CountA(Range("E:E")) + 10
'number of cell with values
j = Application.CountA(Range("J:J")) + 10
For j = 11 To j
temp = Range("J" & j).Value
For i = 11 To i
d = Range("D" & i).Value
Vec = split(d, ",") 'split the cell
d = "" 'clear the string
For x = LBound(vec) To UBound(vec)
If vec(x) = temp Then
vec(x) = 0
End If
d = d & vec(x) & "," 'recreate the string
Next
Range("D" & i).Value = left(d, len(d) - 1) 'save the string without the last ,
Next
Next
you can do this with the below formula - no need for VBA
Make a new column somewhere near column D.
In your new column, use this FIND and Substitute formula:
=IF(NOT(ISERROR(FIND(J:J,D:D))),SUBSTITUTE(D:D,J:J,"0"),D:D)
This formula looks for the value in column J within the cells in column D.
If a match is found, 0 is substituted for the found number. Otherwise, column D is returned.
If you want, you can hide column D to avoid confusion.
in VBA you have a string function called Split(vString, delimiter) that will split a string into tokens using the specified delimiter. See
MSDN Library: VB Split Function
examples:
Mr Spreadsheet John Walkenbach: Split Function examples
VB-Helper
I have data in (Sheet4) columns A to I:
I'm trying to compare data for all rows (Only on column A and B) to see if any of the rows is duplicated, if it is: excel should highlight both rows.
Example:
A B C......I
s 1 x
s 3 w
e 5 q
s 1 o
Row 1 and 4 should be highlighted as values are the same for column A and B.
I shouldn't modify the sheet (no modification to the columns or rows should be done to the sheet), and the number of rows is not always known (not the same for all files).
Is there an easy way (using macros) to do this???
This is an attempt I have tried, but it is increasing my file to 7MB!!!!! I'm sure there should be an easier way to compare rows for an unknown number of rows and just highlight the dupllicates if they exist:
Public Sub duplicate()
Dim errorsCount As Integer
Dim lastrow As Integer
Dim lastrow10 As Integer
errorsCount = 0
lastrow = Sheet4.Cells(Rows.Count, "A").End(xlUp).Row 'is the row number of the last non-blank cell in the specified column
lastrow10 = lastrow
Sheet10.Range("B1:B" & lastrow10).Value = Sheet4.Range("A1:A" & lastrow).Value
Set compareRange = Sheet10.Range(column + "2:" & Sheet10.Range(column + "2").End(xlDown).Address)
For Each a In Sheet10.Range(column + "2:" & Sheet10.Range(column + "2").End(xlDown).Address)
c = a.Value
If c <> Null Or c <> "" Then
If name = "testing" Then
If WorksheetFunction.CountIf(compareRange, c) > 1 Then
a.Interior.ColorIndex = 3
errorsCount = errorsCount + 1
End If
End If
End If
Next a
If errorsCount > 0 Then
MsgBox "Found " + CStr(errorsCount) + " errors"
Else
MsgBox " No errors found."
End If
End Sub
Silly answer to you.
J1 or just duplicate sheet.
J1 =CONCATENATE(A1,"#",B1) > drag down > J:J > conditional format > highlight cells rules > duplicate values.
(* replace the # to any string which you think not possible in the original A:A and B:B.)
I do this all the time.
To collect all duplicates just SORT with color.