Excel get multiple sub-strings from a string - excel

I have got an Excel file with a column named Comments in a sheet called Resources (accessible as Resources[#Comments]), the data looks something similar to,
+=============================================+
| Comments |
+=============================================+
| [7/2] Level changed from 10 to 9 |
| [14/2] Alignment changed from ABC to XYZ |
| [21/2] Location changed from US to UK |
| [28/2] Chapter changed from [blank] to ABCD |
+---------------------------------------------+
| [14/2] Level changed from 5 to 4 |
| [21/2] Location changed from US to UK |
| [21/2] Chapter changed from JKLM to ABCD |
+---------------------------------------------+
| [28/2] Chapter changed from EFGH to MNOP |
+---------------------------------------------+
| [21/2] Location changed from IN to JP |
+---------------------------------------------+
The output I'm looking for should look something like (essentially extracting text between Chapter changed from <SOURCE> to <DESTINATION>),
+=============================================+==============+==============+
| Comments | Old Chapter | New Chapter |
+=============================================+==============+==============+
| [7/2] Level changed from 10 to 9 | [blank] | ABCD |
| [14/2] Alignment changed from ABC to XYZ | | |
| [21/2] Location changed from US to UK | | |
| [28/2] Chapter changed from [blank] to ABCD | | |
+---------------------------------------------+--------------+--------------+
| [14/2] Level changed from 5 to 4 | | |
| [21/2] Location changed from US to UK | | |
| [21/2] Chapter changed from JKLM to ABCD | | |
+---------------------------------------------+--------------+--------------+
| [28/2] Chapter changed from EFGH to MNOP | EFGH | MNOP |
+---------------------------------------------+--------------+--------------+
| [21/2] Location changed from IN to JP | | |
+---------------------------------------------+--------------+--------------+
Notes:
Cell might not have any "Chapter changed" text in which case no processing is required.
"Chapter changed" text is always the last line.
Only want to track the change if it was today (e.g. [28/2] =TEXT(today(), "dd/m")
I think Excel wraps text within "" (double quotes).
I am happy with either Excel formula or VBA script. Already tried stuff like KuTools, =MID(Resources[#Comments],SEARCH("Chapter changed from",Resources[#Comments])+20,SEARCH("to", Resources[#Comments]) - SEARCH("Chapter changed from",Resources[#Comments])-21).
To check the date part I am using, =IF(ISNUMBER(SEARCH("["&TEXT(TODAY(), "dd/m")&"] Chapter changed", Resources[#Comments])), "Yes", "")
Thanks.

It is pretty simple actually...
Spilt the cell contents using vbnewline or Chr(10)
Split on "["
Split on "]"
Check Date
Split on "from"
Split on "to"
Code: Is this what you are trying?
Sub Sample()
Dim cellValue As String
Dim tmpAr As Variant
Dim Dt As String, lastLine As String
Dim OLDc As String, NEWc As String
Dim rng As Range
'~~> Set the range
Set rng = Sheet1.Range("A2")
'~~> Split on Linefeed. It could be Chr(13) as well
tmpAr = Split(rng.Value, Chr(10))
'~~> Get the last line
lastLine = tmpAr(UBound(tmpAr))
'~~> Get the date part
Dt = Split(lastLine, "[")(1)
Dt = Split(Dt, "]")(0)
'~~> Check if it is same as today
If Format(Date, "D/M") = Dt Then
lastLine = Split(lastLine, "from")(1)
OLDc = Trim(Split(lastLine, "to")(0))
NEWc = Trim(Split(lastLine, "to")(1))
rng.Offset(, 1).Value = OLDc
rng.Offset(, 2).Value = NEWc
End If
End Sub

you could use Replace() method of Range object:
Sub DoThat()
Dim cell As Range
With Range("A1", Cells(Rows.Count, 1).End(xlUp))
.Offset(, 1).Resize(, 2).Value = .Value
For Each cell In .Offset(, 1).Cells
If InStr(cell.Value2, Format(Date, "D/M")) > 0 Then
cell.Replace "*from ", ""
cell.Replace " to *", ""
cell.Offset(, 1).Replace "*to ", ""
Else
cell.Resize(, 2).ClearContents
End If
Next
End With
End Sub

Related

Is there a way to transpose certain columns while keeping others and duplicating them in Excel?

I am needing to transpose only a few columns (ex: C:G) into a single column, while maintaining the information in Column A and B.
So if Joe made a sale on Monday Then "Monday" would be in the new Day Column. Then the next row would have Joe again, but this time "Wednesday" in the Day Column. Then, if there are no more values, then move to Steve and do the same thing. I have been stuck on this for a very long time so any advice or new approaches to this would be greatly appreciated. I don't care if it's with a formula or VBA code.
| | A | B | C | D | E | F | G |
+---+-------+-------+--------+---------+-----------+----------+--------+
| 1 | Names | Sales | Monday | Tuesday | Wednesday | Thurday | Friday |
| 2 | Joe | 24500 | Monday | | Wednesday | | |
| 3 | Steve | 15454 | | Tuesday | | | |
| 4 | Emily | 58421 | | Tuesday | Wednesday | Thursday | |
| 5 | Marie | 24582 | Monday | | | | Friday |
+---+-------+-------+--------+---------+-----------+----------+--------+
+---+-------+-------+-----------+
| | A | B | C |
+---+-------+-------+-----------+
| 1 | Names | Sales | Day |
| 2 | Joe | 24500 | Monday |
| 3 | Joe | 24500 | Wednesday |
| 4 | Steve | 15454 | Tuesday |
| 5 | Emily | 58421 | Tuesday |
| 6 | Emily | 58421 | Wednesday |
| 7 | Emily | 58421 | Thursday |
| 8 | Marie | 24582 | Monday |
| 9 | Marie | 24582 | Friday |
+---+-------+-------+-----------+
Wanted to test the new LET() function.
If one has LET() in Office 365 (as of this writing only available to certain insiders)
Put this in the first cell of the output and Excel will spill the results:
=LET(RNG_1,A2:INDEX(A:A,MATCH("zzz",A:A)),RNG_2,B2:INDEX(B:B,MATCH("zzz",A:A)),RNG_3,C2:INDEX(G:G,MATCH("zzz",A:A)),RW,ROWS(RNG_3),CLM,COLUMNS(RNG_3),SEQ,SEQUENCE(RW*CLM,,0),TOT,CHOOSE({1,2,3},INDEX(RNG_1,INT(SEQ/CLM)+1),INDEX(RNG_2,INT(SEQ/CLM)+1),INDEX(RNG_3,INT(SEQ/CLM)+1,MOD(SEQ,CLM)+1)&""),FILTER(TOT,INDEX(TOT,0,3)<>""))
'VBA Macro solution
Sub Transps()
Range("l2:n100").ClearContents
LstRw = Application.WorksheetFunction.CountA(Range("a:a"))
writeRw = 2
For rw = 2 To LstRw
For col = 3 To 7
If Not IsEmpty(Cells(rw, col)) Then
Cells(writeRw, 12) = Cells(rw, 1)
Cells(writeRw, 13) = Cells(rw, 2)
Cells(writeRw, 14) = Cells(rw, col)
writeRw = writeRw + 1
End If
Next col
Next rw
End Sub
Just to offer a further solution based on Office 365 I demonstrate a VBA approach using â–ºWorksheetfunction.Filter() to write transposed blocks of weekday data back to any target:
Sub UnpivotWeekdays()
Dim DataRange As Range
Set DataRange = Sheet1.Range("A2:G6") ' << change to your needs referring to a sheet's Code(Name)
With Sheet2.Range("A2") ' << change to any wanted target cell
Dim i As Long, ii As Long
For i = 1 To DataRange.Rows.Count
'get data blocks resized to 1..5 rows (here: Monday..Friday)
Dim commoninfo: commoninfo = getCommonInfo(DataRange, i)
Dim weekdays: weekdays = getWeekdays(DataRange, i)
Dim cnt As Long: cnt = UBound(weekdays)
'write identical common data to first two columns
.Offset(ii).Resize(cnt, 2).Value = commoninfo
'write weekdays to single column
.Offset(ii, 2).Resize(cnt, 1) = Application.Transpose(weekdays)
'increment current target offsets
ii = ii + cnt
Next
End With
End Sub
Help functions
The help function getWeekdays() uses Worksheetfunction.Filter() and returns a "flat" array of non-empty findings which will be transposed to vertical entries in the calling procedure:
Function getWeekdays(rng As Range, ByVal myRow As Long, Optional startColumn As Long = 3) As Variant()
'Purpose: filter valid weekdays (i.e. return only cells <> "")
'Note : assuming day data in 3rd range column (defaulting startColumn = 3)
Const DaysOfWeek = 5 ' here: Monday .. Friday
Dim ad As String: ad = rng.Offset(0, startColumn).Resize(1, DaysOfWeek).Rows(myRow).Address
On Error Resume Next
getWeekdays = Evaluate("Filter(" & ad & ", " & ad & "<>"""")")
If Err.Number <> 0 Then GoTo NOENTRIES
Exit Function
NOENTRIES:
Dim tmp: ReDim tmp(1 To 1)
getWeekdays = tmp
End Function
The function getCommonInfo() returns an array of the identifying data in the first two columns to be repeated as often as there exist weekday entries:
Function getCommonInfo(rng As Range, ByVal myRow As Long) As Variant()
'Purpose: get common info from first two range columns
getCommonInfo = rng.Offset(myRow - 1).Resize(1, 2).Value
End Function

VBA Codes clash with one another

Can you please advise how I can fix the following codes so that they do not class with each anymore. I apologise that I had to put down a lot of codes here but I really have no idea which of those are making them clash with each other.
So, I have this part to return "Rollup" for any empty Sales and Production cells if "Shipped" in Column AU (47th column).
Private Sub Worksheet_Change(ByVal Target As Range)
Dim counter As Long
Dim lastcolumn As Long
lastColumn = Me.Cells(1, Me.Columns.Count).End(xlToLeft).Column
'Shipped without Title Transfer
If Me.Cells(1, Target.Column).Value = "MB51 Shipped" Then
For counter = 1 To lastColumn
If (Me.Cells(1, counter).Value = "Sales" Or Me.Cells(1, counter).Value = "Production") _
And IsEmpty(Me.Cells(Target.Row, counter).Value) Then
Me.Cells(Target.Row, counter).Value = "Rollup"
End If
Next counter
End If
Then I have this piece to return "x" in column AX (50th column) if the last Sales column has "Title Transfer".
Dim r As Range, r1 As Range, counter As Long
Dim MaxCol As Variant, rg As Range, j As Long
If Not Intersect(Target, Range("N:AP")) Is Nothing And Target.Column Mod 4 = 2 Then
Set r = Intersect(Target, Cells(1, 1).CurrentRegion, Columns(Target.Column).Resize(, 3))
Call DoCells(r)
End If
'Automatically put "x" if Title Transfer in any Sales columns
If Not Intersect(Target, Range("N:AP")) Is Nothing And Target.Column Mod 4 = 2 Then
If Target.CountLarge > 1 Then Exit Sub
Set rg = Range("N" & Target.Row & ":AP" & Target.Row)
MaxCol = 0
For j = Columns("AP").Column To Columns("N").Column Step -4
If Cells(Target.Row, j) <> "" Then
If j > MaxCol Then MaxCol = j
End If
Next
If MaxCol Mod 4 = 2 Then
If Cells(Target.Row, MaxCol).Value = "Title Transfer" Then
Cells(Target.Row, 50).Value = "x"
Else
Cells(Target.Row, 50).Value = ""
End If
End If
End If
'This I have 8 Sales Column, however, I only put 1 line down for demonstration
Set r = Intersect(Target, Cells(1, 1).CurrentRegion, Columns(colSales1).Resize(, 3))
If Not r Is Nothing Then Call DoCells(r)
If Not Intersect(Target, Range("N:AP")) Is Nothing And Target.Column Mod 4 = 2 Then
If Target.CountLarge > 1 Then Exit Sub
Set rg = Range("N" & Target.Row & ":AP" & Target.Row)
MaxCol = Evaluate("=MAX(IF(" & rg.Address & "<>"""",COLUMN(" & rg.Address & ")))")
If MaxCol Mod 4 = 2 Then
If Cells(Target.Row, MaxCol).Value = "Title Transfer" Then
Cells(Target.Row, 50).Value = "x"
Else
Cells(Target.Row, 50).Value = ""
End If
End If
End If
End Sub
Here is the DoCells sub that one of the lines calls up.
Private Sub DoCells(r As Range)
Dim r1 As Range
For Each r1 In r.Cells
With r1
Select Case .Column
Case colSales1, colSales2, colSales3, colSales4, colSales5, colSales6, colSales7, colSales8
Call MasterChange(.Resize(1, 3))
Case colProduction1, colProduction2, colProduction3, colProduction4, colProduction5, colProduction6, colProduction7, colProduction8
Call MasterChange(.Offset(0, -1).Resize(1, 3))
Case colDay1, colDay2, colDay3, colDay4, colDay5, colDay6, colDay7, colDay8
Call MasterChange(.Offset(0, -2).Resize(1, 3))
End Select
End With
Next
End Sub
Here is my data structure using Markdown Table:
| Title | Engine Family | Market Segment | Customer | Engine Model | S/N | Build Spec | ACTL.FINISH | Sales Order | Item | Committed Date | EPS Date | Target | Sales | Production | Day 1 | Status | Sales | Production | Day 2 | Status | Sales | Production | Day 3 | Status | Sales | Production | Day 4 | Status | Sales | Production | Day 5 | Status | Sales | Production | Day 6 | Status | Sales | Production | Day 7 | Status | Sales | Production | Day 8 | Status | Comments | MB51 Shipped | FPS? | Plant | Title Transfer |
|--------|---------------|----------------|----------|--------------|-----|------------|-------------|-------------|------|----------------|------------|--------|-------|------------|-------|--------|----------------|------------|----------------|--------|---------|------------|---------|------------------|---------|------------|---------|------------------|---------|------------|---------|------------------|---------|------------|---------|------------------|---------|------------|---------|------------------|---------|------------|---------|------------------|----------|--------------|------|-------|----------------|
| Rollup | PS | APU | ABC | 46C12 | 1 | BS1 | 0000-00-00 | 101 | 450 | 2019-12-31 | 2019-12-31 | Rollup | Green | Rollup | Green | Sales | Title Transfer | Yellow | Title Transfer | Sales | | | | Sales/Production | | | | Sales/Production | | | | Sales/Production | | | | Sales/Production | | | | Sales/Production | | | | Sales/Production | | | | | x |
| Yellow | PS | FEP | ADG | PS3 | 3 | BS3 | 0000-00-00 | 103 | 180 | 2019-12-16 | 2019-12-20 | Yellow | Green | Rollup | Green | Sales | Title Transfer | Yellow | Title Transfer | Sales | Rollup | Rollup | Rollup | Sales/Production | Rollup | Rollup | Rollup | Sales/Production | Rollup | Rollup | Rollup | Sales/Production | Rollup | Rollup | Rollup | Sales/Production | Rollup | Rollup | Rollup | Sales/Production | Rollup | Rollup | Rollup | Sales/Production | | Shipped | | | |
| Rollup | T6T | OEM | FEDS | 67C | 5 | BS5 | 0000-00-00 | 105 | 250 | 2019-12-23 | 2019-12-22 | Rollup | Green | Rollup | Green | Sales | Title Transfer | Yellow | Title Transfer | Sales | Shipped | Rollup | Shipped | Sales/Production | Shipped | Rollup | Shipped | Sales/Production | Shipped | Rollup | Shipped | Sales/Production | Shipped | Rollup | Shipped | Sales/Production | Shipped | Rollup | Shipped | Sales/Production | Shipped | Rollup | Shipped | Sales/Production | | Shipped | | | x |
FYI, I have 8 Days in total, each Day is a combination of 4 columns with the exact same order: Sales, Production, Day, Status. The range is from column N to column BS (or AS in an actual Excel workbook).
As seen from the table:
1) the 1st row did exactly what I wanted. It did evaluate correctly the "Title Transfer" in column Sales/column R (of Day 2) to be the last Sales column that has "Title Transfer" and return an "x" in column BX (or column AX in my excel file).
2) the 2nd row, the codes returned both correct and wrong results.
I had put "Title Transfer" in a Sales column first, which the Macro then returned an "x" in column BX. That's correct.
However, when I put "Shipped" in column BU after having put "Title Transfer" first in column BX, the "x" was replaced by the Shipped codes I posted above. It did return "Rollup" for all empty Sales and Production cells when I put "Shipped" in column BU (47th column or column AU in my excel file). But the "x" to indicate Title Transfer was gone.
So here comes the problem I've been struggling with for the past week. Can you please advise how I can fix this problem?
3) the 3rd row is what I wanted my codes did if both "Shipped" in column BU and "x" in column BX (apparently it won't work)
To be short, my codes should have done the following:
1) If "Shipped" in column BU (AU in an actual Excel file) and no "x" in column BX (AX in an actual Excel file), then return "Rollup" for all empty Sales and Production cells
2) If "Title Transfer" in the last Sales column and no "Shipped" in column BU (AU in an actual Excel file), return "x" in column BX (AX in an actual Excel file)
3) If "Title Transfer" in the last Sales column (has to happen first) and "Shipped" in column BU (happens later) (AU in an actual Excel file), return "x" in column BX and "Shipped" in all empty Sales and Production cells
Can you please help how to get it to work that way? Thanks a lot and please let me know if you need more info.
Ps: This is what MasterChange has:
Public Sub MasterChange(SPD As Range)
Dim rSales As Range
Dim rProduction As Range
Dim rDay As Range
Set rSales = SPD.Cells(1, 1)
Set rProduction = SPD.Cells(1, 2)
Set rDay = SPD.Cells(1, 3)
Application.EnableEvents = False
If rSales = "Rollup" And rProduction = "Rollup" Then
rDay = "Rollup"
ElseIf rSales = "Rollup" And rProduction = "Green" Then
rDay = "Green"
ElseIf rSales = "Rollup" And rProduction = "Yellow" Then
rDay = "Yellow"
'I have approximately 40 Ifs statements like those but above are just a few for demonstration
End If
Application.EnableEvents = True
End Sub

Storing the first value in a sequence and use the stored values where the condition meets

I have this table and the VBA code has to fetch Value from Product where the Primary value is Yes. But, Value has to be the First Value in the Sequence.
+---------+---------+---------+
| Product | Results | Primary |
+---------+---------+---------+
| A | | |
| B | | Yes |
| C | | Yes |
| D | | |
| E | | Yes |
| F | | |
| G | | Yes |
| H | | Yes |
| I | | |
+---------+---------+---------+
Expecting results:
+---------+---------+---------+
| Product | Results | Primary |
+---------+---------+---------+
| A | | |
| B | A | Yes |
| C | A | Yes |
| D | | |
| E | D | Yes |
| F | | |
| G | F | Yes |
| H | F | Yes |
| I | | |
+---------+---------+---------+
I have tried this below vba code, but doesn't work as i expected.
Sub test()
Dim i As Long
Dim lr As Long
lr = ActiveSheet.UsedRange.Rows.Count
For i = 2 To lr
If Range("D" & i).Value = "Yes" Then
Range("C" & i).Value = Range("B" & i - 1).Value
End If
Next
End Sub
Excel Formula
Here is an example of how your formula can look. This first looks to see if the primary field is "Yes". If so, then it checks if the previous result also was a yes, and grabs it's the result if so. Otherwise, it grabs the first value based on your example.
=IF($C2="Yes", IF($C1="Yes", $B1, $A1),"")
Adjust this as needed!
VBA Code
I would suggest creating a way of finding your headers, that way it is easier to update down the road in case it changes or there are more fields added. Below I added an example of what I would attempt to do.
I used a helper function (Inject) to build the actual formula and make it easier to read/debug if there are issues.
Feel free to add your own custom error handling as well.
Just note this is one of many ways you could tackle this. I could even break this formula into even smaller components to abstract as much of it as possible.
Option Explicit
Private Sub AddResultsToTable()
Dim Ws As Worksheet
Set Ws = ActiveSheet
'FIND COLUMN HEADERS TO USE IN FORMULA REFERENCES
With Ws.UsedRange
On Error GoTo Catch
Dim Product As Range
Set Product = .Find("Product")
Dim Results As Range
Set Results = .Find("Results")
Dim Primary As Range
Set Primary = .Find("Primary")
End With
'CREATE FORMULA. Example: =IF($C2="Yes", IF($C1="Yes", $B1, $A1),"")
Dim CustomFormula As String
CustomFormula = Inject("=IF(${0}='Yes', IF(${1}='Yes', ${2}, ${3}),'')", _
Primary.Offset(1).Address(False, True), _
Primary.Address(False, True), _
Results.Address(False, True), _
Product.Address(False, True) _
)
'SET FIRST RANGE EQUAL TO FORMULA & AUTOFILL FORMULA DOWN
With Results.Offset(1)
.Value = CustomFormula
.AutoFill Range(.Address, Ws.Cells(Ws.Rows.Count, Product.Column).End(xlUp).Offset(, 1))
End With
Exit Sub
Catch:
'You can do your error handling here.
MsgBox Err.Description, vbCritical
End Sub
'METHOD THAT ALLOWS A STRING TO BE REPLACED WITH VARIABLES AND SPECIAL CHARACTERS
Public Function Inject(ByVal Source As String, ParamArray Args() As Variant) As String
'#AUTHOR: ROBERT TODAR
'#EXAMPLE: Inject("${0}, ${1}!", "Hello", "Robert") --> Hello, Robert!
'REPLACE SINGLE QUOTES WITH DOUBLE QUOTES
Inject = Source
Inject = Replace(Inject, "'", """")
'REPLACE ${#} WITH VALUES STORED IN THE VALUE IN THAT INDEX.
Dim Index As Integer
For Index = LBound(Args, 1) To UBound(Args, 1)
Inject = Replace(Inject, "${" & Index & "}", Args(Index), , , vbTextCompare)
Next Index
End Function
Assuming cols A B C use the below formula in B2
=If(C2="yes", if(B1="",A1,B1),"")
Copy this to all the linea below.
This will work as long as the first item is not primary.
U can even include this formula in vba and do the copy paste in vba

Retrieving name and location of specific Shapes from worksheet with VBA

This is a follow up to my previous question (Retrieving information of OLEObjects from Workbook with VBA)
Scenario: I am trying to retrieve data from a worksheet. The data might be normal strings or number or might be encased in check boxed (checked or not).
Data example:
+---------+-------+------------------+------+------------------+
| item1 | 2004 | | | |
+---------+-------+------------------+------+------------------+
| value x | rfd | checkbox for rfd | nfd | checkbox for nfd |
+---------+-------+------------------+------+------------------+
| ident | test7 | call3 | | |
+---------+-------+------------------+------+------------------+
Obs: In this example the "checkbox for rfd/nfd" is a normal checkbox (either form or activex), and depending on the item in that sheet, either might be selected.
Objective: What I am trying to do is read the worksheet in 2 steps: First read all the data that is directly called, so I use the code:
Sub Test_retrieve()
' this will get all non object values from the sheet
Dim array_test As Variant
Dim i As Long, j As Long
array_test = ThisWorkbook.Sheets(1).UsedRange
For i = 1 To ThisWorkbook.Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
For j = 1 To ThisWorkbook.Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column
ThisWorkbook.Sheets(2).Cells(i, j) = array_test(i, j)
Next j
Next i
End Sub
to get:
+---------+-------+------------------+------+------------------+
| item1 | 2004 | | | |
+---------+-------+------------------+------+------------------+
| value x | rfd | | nfd | |
+---------+-------+------------------+------+------------------+
| ident | test7 | call3 | | |
+---------+-------+------------------+------+------------------+
Next I am trying to reach all the objectives/shapes in my worksheet. I used the following code to get name, value (checked of not) and location of all activex objects:
Sub getavticeboxvalue()
' this will get the names and values (as binary) of all the activex controlbox objects in the sheet
Dim objx As Object
Dim i As Long
i = 1
For Each objx In ThisWorkbook.Sheets(1).OLEObjects
If objx.Object.Value = True Then
ThisWorkbook.Sheets(3).Cells(i, 1).Value = 1
ThisWorkbook.Sheets(3).Cells(i, 2).Value = objx.Name
ThisWorkbook.Sheets(3).Cells(i, 3).Value = objx.BottomRightCell.Address
ElseIf objx.Object.Value = False Then
ThisWorkbook.Sheets(3).Cells(i, 1).Value = 0
ThisWorkbook.Sheets(3).Cells(i, 2).Value = objx.Name
ThisWorkbook.Sheets(3).Cells(i, 3).Value = objx.BottomRightCell.Address
End If
i = i + 1
Next objx
End Sub
Which yields something like:
+-------+-----------+----------+
| value | name | location |
+-------+-----------+----------+
| 0 | checkbox1 | $C$2 |
+-------+-----------+----------+
| 1 | checkbox2 | $E$2 |
+-------+-----------+----------+
I would then proceed to feed the values (1s and 0s), to the first table, in the place where the checkboxes originally where (location).
Issue: When I try the same procedure for Form Control (instead of activex), I have less options, and although I can look for them (ThisWorkbook.Sheets(1).Shapes.Type = 8) I cannot find their name or location.
Question: Is there a way to find their name and location? Is there a more efficient way to reach the result?
Objective:
+---------+-------+------------------+
| item1 | 2004 | | | |
+---------+-------+------------------+
| value x | rfd | 0 | nfd | 1 |
+---------+-------+------------------+
| ident | test7 | call3 | | |
+---------+-------+------------------+

Convert from one long colum, to multiple columns

I need a little help, or a VBA script that can convert a big dataset (960000 rows) in the format like below. All the data are in one column
TRIP_ID | OBJECTID | CPR_VEJNAV | ADM_VEJSTA | ADM_VEJKLA | vejid | vejkl | Shape_Length
2626 | value | value | value | value | value | value | value
..
..
2626 | value | value | value | value | value | value | value
64646 | value | value | value | value | value | value | value
..
..
..
64646 | value | value | value | value | value | value | value
I would like to convert the data into multiple columns, one column for each TRIP_ID, like this:
TRIP_ID | ..... | TRIP_ID ..... | And so on
2626 | ..... | 64646 .....
..
..
2626 | ...... | 64646 .....
And so on, I have around 1800 TRIP_ID's
In short terms:
Convert from one long column, to multiple columns based on TRIP_ID
Always make a backup of your data before running someone else's code
Sub SplitToColumns()
Dim rCell As Range
Dim sCurrent As String
Dim rLast As Range
Dim lRowStart As Long
Application.EnableEvents = False
Set rLast = Sheet1.Range("A2").End(xlDown).Offset(1, 0)
rLast.Value = "End"
For Each rCell In Sheet1.Range("A2", rLast).Cells
If Split(rCell.Value, "|")(0) <> sCurrent Then
If lRowStart > 1 Then
rCell.Offset(lRowStart - rCell.Row, 0).Resize(rCell.Row - lRowStart, 1).Copy
Sheet1.Cells(2, Sheet1.Columns.Count).End(xlToLeft).Offset(0, 1).Resize(rCell.Row - lRowStart, 1).PasteSpecial xlValues
End If
lRowStart = rCell.Row
sCurrent = Split(rCell.Value, "|")(0)
End If
Next rCell
rLast.ClearContents
Application.CutCopyMode = False
Application.EnableEvents = True
End Sub

Resources