Copy and paste values into one cell - excel

I want to create a VBA code where it could copy all the unique file owner emails into one cell and all the file locations into the cell next to it, being separated by a comma. Is that possible? I created a code to grab the unique values and pasted into cell L1 and create a table, and this is what I have so far:
This is an example of what Excel would look like
This is an example what I want the VBA code to do
Public Sub unique_emails()
Columns("B:B").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("L1" _
), Unique:=True
Range("L1").Select
Dim tbl As ListObject
Dim rng As Range
Set rng = Range(Range("L1"), Range("L1").SpecialCells(xlLastCell))
Set tbl = ActiveSheet.ListObjects.Add(xlSrcRange, rng, , xlYes)
tbl.TableStyle = "TableStyleMedium16"
End Sub

Unique Delimited (Dictionary)
Adjust the values in the constants section.
Option Explicit
Public Sub unique_emails()
Const sFirst As String = "A1"
Const dFirst As String = "L1"
Const Delimiter As String = ", "
' Worksheet
Dim ws As Worksheet: Set ws = ActiveSheet
' Source Range
Dim rg As Range
With ws.Range(sFirst).Resize(, 2)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If lCell Is Nothing Then Exit Sub
Set rg = .Resize(lCell.Row - .Row + 1)
End With
Dim rCount As Long: rCount = rg.Rows.Count
' Source Range to Array
Dim Data As Variant: Data = rg.Value
Dim n As Long
If rCount > 1 Then
' Array to Dictionary
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim Key As Variant
For n = 2 To rCount
Key = Data(n, 2)
If Not IsError(Key) Then
If Len(Key) > 0 Then
If dict.Exists(Key) Then
dict(Key) = dict(Key) & Delimiter & Data(n, 1)
Else
dict(Key) = Data(n, 1)
End If
End If
End If
Next n
' Dictionary to Array
n = 1
For Each Key In dict.Keys
n = n + 1
Data(n, 1) = Key
Data(n, 2) = dict(Key)
Next Key
Else
n = 1
End If
' Switch Headers
Key = Data(1, 1): Data(1, 1) = Data(1, 2): Data(1, 2) = Key
' Array to Destination Range
With ws.Range(dFirst).Resize(, 2)
.Resize(n).Value = Data
.Resize(.Worksheet.Rows.Count - .Row - n + 1).Offset(n).ClearContents
End With
End Sub

Related

VBA get unique value from range and result input every second row

I have two macros that I would like to combine but somehow its not going well...
I want a macro that will get only unique values from a range and input them into another sheet every second row starting from row no 3
Could anyone tell me how should I combine those two macros?
I have tried to change .Font.Size = 20 with Application.Transpose(objDict.keys) but it didn't work.
Sub UniqueValue()
Dim X
Dim objDict As Object
Dim lngRow As Long
Set objDict = CreateObject("Scripting.Dictionary")
X = Application.Transpose(Range([a1], Cells(Rows.Count, "A").End(xlUp)))
For lngRow = 1 To UBound(X, 1)
objDict(X(lngRow)) = 1
Next
Range("F1:F" & objDict.Count) = Application.Transpose(objDict.keys)
End Sub
Sub EverySecond()
Dim EndRow As Long
EndRow = Range("A" & Rows.Count).End(xlUp).Row
For ColNum = 5 To EndRow Step 2
Range(Cells(ColNum, 2), Cells(ColNum, 2)).Font.Size = 20
Next ColNum
End Sub
Copy Unique Values to Every Other Row
Option Explicit
Sub UniqueEveryOther()
Const sName As String = "Sheet1"
Const sFirstCellAddress As String = "A2"
Const dName As String = "Sheet2"
Const dFirstCellAddress As String = "A2"
Dim wb As Workbook: Set wb = ThisWorkbook
' Reference the source range.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim srg As Range
Dim srCount As Long
With sws.Range(sFirstCellAddress)
Dim lCell As Range: Set lCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub
srCount = lCell.Row - .Row + 1
Set srg = .Resize(srCount)
End With
' Write the values from the source range to an array.
1
Dim Data As Variant
If srCount = 1 Then ' one cell
ReDim Data(1 To 1, 1 To 1): Data(1, 1) = srg.Value
Else ' multiple cells
Data = srg.Value
End If
' Write the unqiue values from the array to a dictionary.
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim Key As Variant
Dim r As Long
For r = 1 To srCount
Key = Data(r, 1)
If Not IsError(Key) Then
If Len(Key) > 0 Then
dict(Key) = Empty
End If
End If
Next r
If dict.Count = 0 Then Exit Sub
' Write the unqiue values from the dictionary to the array.
ReDim Data(1 To 2 * dict.Count - 1, 1 To 1)
r = -1
For Each Key In dict.Keys
r = r + 2
Data(r, 1) = Key
Next Key
' Write the unique values from the array to the destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dFirstCellAddress)
.Resize(r).Value = Data
.Resize(dws.Rows.Count - .Row - r + 1).Offset(r).Clear
'.EntireColumn = AutoFit
End With
'wb.Save
MsgBox "Uniques populated.", vbInformation
End Sub

Look for a cell value (more than one instance) in a column then copy corresponding row values to another row (against other cell value)

I want to look for value of Forecast in cell (F column) (more than one instance - unique key is Prod and Cust), then copy corresponding row values to other rows identified by Edited Forecast value in another cell (more than one instance - unique key is Prod and Cust (same column).)
This is only copying Row values.
Private AutomationObject As Object
Sub Save ()
Dim Worksheet as Worksheet
Set Worksheet = ActiveWorkbook.Worksheets("Sheet")
Worksheet.Range("M18:AX18").Value = Worksheet.Range("M15:AX15").Value
End Sub
Fill Blanks (Unique Dictionary)
Option Explicit
Sub FillBlanks()
Const sFirstCellAddress As String = "D3"
Const sDelimiter As String = "#"
Const dCols As String = "I:K"
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim srg As Range
Dim rCount As Long
With ws.Range(sFirstCellAddress)
Dim lCell As Range: Set lCell = .Resize(ws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub
rCount = lCell.Row - .Row + 1
Set srg = .Resize(rCount, 2)
End With
Dim sData As Variant: sData = srg.Value
Dim drg As Range: Set drg = srg.EntireRow.Columns(dCols)
Dim dcCount As Long: dcCount = drg.Columns.Count
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim rg As Range
Dim r As Long
Dim sString As String
For r = 1 To rCount
sString = sData(r, 1) & sDelimiter & sData(r, 2)
If Application.CountBlank(drg.Rows(r)) = dcCount Then
If dict.Exists(sString) Then
If IsArray(dict(sString)) Then
drg.Rows(r).Value = dict(sString)
Else
dict(sString).Add drg.Rows(r)
End If
Else
Set dict(sString) = New Collection
dict(sString).Add drg.Rows(r)
End If
Else
If dict.Exists(sString) Then
If IsArray(dict(sString)) Then
'drg.Rows(r).Value = dict(sString) ' overwrite!?
Else
For Each rg In dict(sString)
rg.Value = drg.Rows(r).Value
Next rg
dict(sString) = drg.Rows(r).Value
End If
Else
dict(sString) = drg.Rows(r).Value
End If
End If
Next r
MsgBox "Data updated.", vbInformation
End Sub

how do i split multiple lines of data in one cell in excel

I receive this data in one cell as an export from TV. I need to split this data so that it appears in individual rows. I would prefer to do this via VBA and not formulas as I need it manipulated automatically without much human intervention. Does anyone know how I can do this? Text to Columns does not work for this example unfortunately.
The top 2 lines BINANCE:USDT PAIRS AND Oversold need to be on the lines with the Gala and ICP.
Split Multi-Line Cell to Another Worksheet
Adjust the values in the constants section.
Option Explicit
Sub SplitCoins()
' Source
Const sName As String = "Sheet1"
Const sfCellAddress As String = "A2"
Const sDelimiter As String = vbLf ' maybe 'vbCrLf'?
' Destination
Const dName As String = "Sheet2"
Const dfCellAddress As String = "A2"
Const dcCount As Long = 7
Const dhCount As Long = 2
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
If sws.AutoFilterMode Then sws.AutoFilterMode = False
Dim sData As Variant
sData = GetColumnRange(RefColumn(sws.Range(sfCellAddress)))
Dim srCount As Long: srCount = UBound(sData, 1)
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dCell As Range: Set dCell = dws.Range(dfCellAddress)
Dim drCount As Long
Dim sr As Long
Dim dr As Long
Dim c As Long
Dim sSubStrings() As String
Dim h67SubStrings() As String
Dim sString As String
Dim h1String As String
Dim h3String As String
Dim hcString As String
Dim hbString As String
Dim huString As String
Dim h6String As String
Dim h7string As String
For sr = 1 To srCount
sString = CStr(sData(sr, 1))
If Len(sString) > 0 Then
sSubStrings = Split(sString, sDelimiter)
drCount = UBound(sSubStrings) - LBound(sSubStrings) - dhCount + 1
ReDim dData(1 To drCount, 1 To dcCount)
dr = 0
For c = 2 To UBound(sSubStrings)
dr = dr + 1
h1String = sSubStrings(0)
dData(dr, 1) = h1String
h3String = sSubStrings(c)
hcString = Left(h3String, InStr(1, h3String, " ") - 1)
dData(dr, 2) = hcString
hbString = Left(h1String, InStr(1, h1String, ":"))
huString = Split(Right(h1String, Len(h1String) _
- Len(hbString)), " ")(0)
dData(dr, 3) = huString
dData(dr, 4) = hbString & hcString & huString
dData(dr, 5) = sSubStrings(1)
h67SubStrings = Split(h3String, " ")
dData(dr, 6) = Round(Split(h67SubStrings(1), ":")(1), 0)
dData(dr, 7) = Round(Split(h67SubStrings(2), ":")(1), 0)
' If your decimal separator is a comma then use:
'dData(dr, 6) = Round(Replace(Split(h67SubStrings(1), ":")(1), _
".", ","), 0)
'dData(dr, 7) = Round(Replace(Split(h67SubStrings(2), ":")(1), _
".", ","), 0)
Next c
dCell.Resize(drCount, dcCount).Value = dData
Set dCell = dCell.Offset(drCount)
Erase dData
End If
Next sr
MsgBox "Data split.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Writes the values from a column ('ColumnNumber')
' of a range ('rg') to a 2D one-based one-column array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetColumnRange( _
ByVal rg As Range, _
Optional ByVal ColumnNumber As Long = 1) _
As Variant
If rg Is Nothing Then Exit Function
If ColumnNumber < 1 Then Exit Function
If ColumnNumber > rg.Columns.Count Then Exit Function
With rg.Columns(ColumnNumber)
If rg.Rows.Count = 1 Then
Dim Data As Variant: ReDim Data(1 To 1, 1 To 1): Data(1, 1) = .Value
GetColumnRange = Data
Else
GetColumnRange = .Value
End If
End With
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to the one-column range from the first cell
' of a range ('FirstCell') to the bottom-most non-empty cell
' of the first cell's worksheet column.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumn( _
ByVal FirstCell As Range) _
As Range
If FirstCell Is Nothing Then Exit Function
With FirstCell.Cells(1)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Function
Set RefColumn = .Resize(lCell.Row - .Row + 1)
End With
End Function

I need to populate a combobox based on a column on a worksheet

I have a combobox on a userform that is currently populated by a column in a table. Column A This column has a tooling number where two numbers can be exactly the same except for the letter on the end. (Cells A5 and A6 for example) how can I populate the combobox so that it only includes the latest version of that number?
Populate Combo Box Unique with a Twist
Adjust the first cell address, the worksheet, and the combo box.
Option Explicit
Sub PopulateComboUnique()
Const First As String = "A2"
Dim rg As Range: Set rg = RefColumn(Sheet1.Range(First))
If rg Is Nothing Then Exit Sub ' empty column range
Dim sData As Variant: sData = GetColumnRange(rg)
Dim dData As Variant: dData = ArrUniqueSpecial(sData)
If IsEmpty(dData) Then Exit Sub ' no unique values
Sheet1.ComboBox1.List = dData
' Dim n As Long
' For n = LBound(dData) To UBound(dData)
' Debug.Print dData(n)
' Next n
End Sub
Function RefColumn( _
ByVal FirstCellRange As Range) _
As Range
If FirstCellRange Is Nothing Then Exit Function
With FirstCellRange.Cells(1)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Function
Set RefColumn = .Resize(lCell.Row - .Row + 1)
End With
End Function
Function GetColumnRange( _
ByVal rg As Range) _
As Variant
If rg Is Nothing Then Exit Function
Dim cData As Variant
With rg.Columns(1)
If .Rows.Count = 1 Then
ReDim cData(1 To 1, 1 To 1): cData(1, 1) = .Value
Else
cData = .Value
End If
End With
GetColumnRange = cData
End Function
Function ArrUniqueSpecial( _
ByVal sData As Variant) _
As Variant
If IsEmpty(sData) Then Exit Function
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim Key As Variant
Dim r As Long
For r = 1 To UBound(sData, 1)
Key = sData(r, 1)
If Not IsError(Key) Then
If Len(Key) > 1 Then ' not allowing zero or one character
dict(Left(Key, Len(Key) - 1)) = Right(Key, 1)
End If
End If
Next r
If dict.Count = 0 Then Exit Function
Dim dData() As String: ReDim dData(1 To dict.Count)
r = 0
For Each Key In dict.Keys
r = r + 1
dData(r) = Key & dict(Key)
Next Key
ArrUniqueSpecial = dData
End Function

MS Excel Macro: inserting x rows based on cell value

We have a spreadsheet of hundreds of Employees and their respective roles that looks like this:
We need to reformat this spreadsheet so that each role is its own separate line item:
We found a VBA Macro that allows us to insert a row if "/" is found in our Roles column, but it only inserts one row instead of based on the number of roles that person has. The rows inserted are also blank.
Sub Insertrowbelow()
'updateby Extendoffice
Dim i As Long
Dim xLast As Long
Dim xRng As Range
Dim xTxt As String
On Error Resume Next
xTxt = Application.ActiveWindow.RangeSelection.Address
Set xRng = Application.InputBox("please select the column with specific text:", "Kutools for Excel", xTxt, , , , , 8)
If xRng Is Nothing Then Exit Sub
If (xRng.Columns.Count > 1) Then
MsgBox "the selected range must be one column", , "Kutools for Excel"
Exit Sub
End If
xLast = xRng.Rows.Count
For i = xLast To 1 Step -1
If InStr(1, xRng.Cells(i, 1).Value, "/") > 0 Then
Rows(xRng.Cells(i + 1, 1).Row).Insert shift:=xlDown
End If
Next
End Sub
Is there a way to add on to this code snippet so that we can get our spreadsheet formatted correctly?
You can use Split to split the roles into separate roles. The rest of the code is boilerplate.
SourceRow = 1
DestinationRow = 1
For SourceRow = 1 To LastSourceRow
Employee = SourceWorksheet.Cells(SourceRow, 1).Value
Roles = Split(SourceWorksheet.Cells(SourceRow, 2).Value, "/")
For i = LBound(Roles) To UBound(Roles)
DestinationWorksheet.Cells(DestinationRow, 1).Value = Employee
DestinationWorksheet.Cells(DestinationRow, 2).Value = Roles(i)
DestinationRow = DestinationRow + 1
Next i
Next SourceRow
Split Column
Adjust the values in the constants section.
Option Explicit
Sub unPivot()
Const wsName As String = "Sheet1"
Const HeaderRow As Long = 1
Const Header As String = "Employee"
Const Delimiter As String = " / "
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sCell As Range
With wb.Worksheets(wsName).Rows(HeaderRow)
Set sCell = .Find(Header, .Cells(.Cells.Count), xlFormulas, xlWhole)
End With
If sCell Is Nothing Then
MsgBox "The header '" & Header & "' was not found.", _
vbCritical, "Missing Header"
Exit Sub
End If
Dim dcell As Range: Set dcell = sCell.Offset(1)
Dim srg As Range
With dcell
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then
MsgBox "No data found.", vbCritical, "No Data"
Exit Sub
End If
Set srg = .Resize(lCell.Row - .Row + 1, 2)
End With
Dim Data As Variant: Data = srg.Value
Dim srCount As Long: srCount = UBound(Data, 1)
ReDim Preserve Data(1 To srCount, 1 To 3)
Dim drCount As Long
Dim r As Long
For r = 1 To srCount
Data(r, 2) = Split(Data(r, 2), Delimiter)
Data(r, 3) = UBound(Data(r, 2))
drCount = drCount + Data(r, 3) + 1
Next r
Dim Result As Variant: ReDim Result(1 To drCount, 1 To 2)
Dim n As Long
Dim k As Long
For r = 1 To srCount
For n = 0 To Data(r, 3)
k = k + 1
Result(k, 1) = Data(r, 1)
Result(k, 2) = Data(r, 2)(n)
Next n
Next r
With dcell.Resize(, 2)
.Resize(k).Value = Result
'.Resize(.Worksheet.Rows.Count - .Row - k + 1).Offset(k).ClearContents
End With
End Sub

Resources