I'm a newbie to Excel VBA and having some problem. I am creating a Macro which will take a .dat file (imports like a .txt file) and puts the filename in the first row and then all the data underneath it starting with row 2. Then the program loops and starts the process again 3 rows over (the data has many rows but only 3 columns).
Currently my Macro will put the imported data correctly, but the filename is not looping correctly. It will input the filename into A1, loops inputs filename into D3 while deleting filename from A1. I can't figure out what's going wrong.
Sub ImportDataFiles()
'call out variables
Dim fName As String, LastCol As Long, fileName As String, fso As Object
'loop start
BEGINNING:
LastCol = Cells(1, Columns.Count).End(xlToLeft).Column
fName = Application.GetOpenFilename("All Files, *.dat")
Set fso = CreateObject("Scripting.FileSystemObject")
fileName = fso.GetFilename(fName)
'fileName is just the file name from the path
Range(Cells(1, LastCol).Address).Value = fileName
If fName = "False" Then Exit Sub
'Imports data from text file
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & fName, _
Destination:=Cells(2, LastCol))
.TextFileStartRow = 30
.TextFileParseType = xlDelimited
.TextFileConsecutiveDelimiter = True
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = True
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, _
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.Refresh BackgroundQuery:=False
'loop end
If MsgBox("Do you want to do it again?", vbYesNo) = vbYes Then GoTo BEGINNING
End With
End Sub
This will get the column number of the last occupied cell in Row1 (or the first cell if there's nothing on the row)
LastCol = Cells(1, Columns.Count).End(xlToLeft).Column
If you start populating content at that position you will (except in the empty row case) overwrite the content in that cell.
LastCol = Cells(1, Columns.Count).End(xlToLeft).Column + 1
Gives you the first empty cell [from the right] on that row. But that doesn't account for the content in the imported file, which has multiple columns. If your imported file has 3 columns then you need to offset further...
To change from wide to long format, simply change the LastCol to LastRow with changes to the following four lines in code.
Dim ... LastRow As Long, ...
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
...
Range(Cells(LastRow + 1, 1).Address).Value = fileName
...
Destination:=Cells(LastRow + 2, 1))
This also resolves your overwriting of FileName and allows you to continue on with subsequent .dat file imports.
Related
I want to consolidate two worksheets on the basis of a "Register No." in a third worksheet.
Workbook:
Tabelle1: Consolidated Worksheet //
Tabelle2: Input Data1 //
Tabelle3: Input Data2
Notes:
At first the "Register No." can only be found in Tabelle2 & Tabelle3 in column A.
Because Tabelle1 has also a different column sequence than Tabelle2 & Tabelle3 I am using vLookup to paste the data to the right columns in Tabelle1.
Idea:
1. Step
Pasting Tabelle2 Data, including "Register No.", to the right columns in Tabelle1 via vLookup. Note: This means "Register No." to Tabelle 1 column A.
2. Step
Pasting Tabelle3 Data to right rows and columns in Tabelle1 via vLookup.
As Tabelle3 contains more "Register No." than Tabelle2, I want my code to check the "Register No." in Tabelle1 column A and copy the corresponding data from Tabelle3.
ERROR:
The 2. Step is not working.
Runtime-Error '1004'
For example:
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 2, False)
Next i
Does anyone know what is wrong with my code? Thanks a lot :)
My Code:
Sub ConsolidateData()
Dim lastrow As Long
lastrow = Tabelle2.Range("A" & Rows.Count).End(xlUp).Row
Set myrange = Tabelle2.UsedRange
For i = 2 To lastrow
Tabelle1.Cells(7 + i, 1) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 1, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(7 + i, 3) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 2, False)
Next i
For i = 2 To lastrow
Tabelle1.Cells(7 + i, 6) = Application.WorksheetFunction.VLookup(Tabelle2.Cells(i, 1), myrange, 3, False)
Next i
Dim lastrow2 As Long
lastrow2 = Tabelle3.Range("A" & Rows.Count).End(xlUp).Row
Set myrange2 = Tabelle3.UsedRange
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 2) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 2, False)
Next i
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 4) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 3, False)
Next i
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 5) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 4, False)
Next i
For i = 2 To lastrow2
Tabelle1.Cells(7 + i, 7) = Application.WorksheetFunction.VLookup(Tabelle1.Cells(i, 1), myrange2, 5, False)
Next i
End Sub
I think the problem is the way you are referencing your worksheets. You are using the Worksheet.CodeName vs the Worksheet.Name of the worksheet.
Look at my example below and you will see that the Worksheet.CodeName and Worksheet.Name do not match.
Worksheet.CodeName is the 1st part of the name and Worksheet.Name is what's shown in parentheses. Therefore the Worksheet.CodeName for the second worksheet is Sheet5, whereas the Worksheet.Name is Sheet6.
This is because I deleted a worksheet and excel, behind the scenes, renamed the Worksheet.CodeName reference.
To use what you see when looking at the tabs in the workbook you need to reference it by Worksheet.Name, not Worksheet.CodeName.
Sub testPickingWorksheets()
' This code fails
a = Sheet6.Range("A1").Value
MsgBox (a)
' This code works
a = Worksheets("Sheet6").Range("A1").Value
MsgBox (a)
End Sub
As you can see from the code above, you need to use the Worksheets() Ojbect with the Worksheet.Name in "quotes" instead of directly referencing the Worksheet.CodeName.
I hope you can help. I have a piece of code and it works relatively well.
What it does is it allows a user to click on a command button which opens up a dialog box. The user then selects another excel sheet, then the code identifies duplicates consolidates these duplicates creating a new row of data with the earliest available start date and latest available end date and then deletes the duplicates
So in Pic 1 you can see the selected sheet has duplicate entries and multiple start and end dates for these duplicate entries
Pic 1
Pic 2 shows the sheet after the code has executed
You can see in Pic 2 that the duplicates have been consolidated and a row of data with the earliest start date and latest end date is left
Agnholt Jørgen Steen is correct
Andersen Anders Nyboe is correct
But it only works if the duplicates are directly under eachother if they are not as in the case with
Christensen Tove and Christensen Trine Tang my code is unable to identify the duplicates and it does not consolidate or work the dates.
Can my code be amended to fix this issue of duplicates not being directly underneath each other?
My code is below as always and all help is greatly appreciated.
MY CODE
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
So i have amended the code to sort Column B but it still leave duplicates
my Code with the sort added is below again any help is greatly appreciated.
CODE
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
lastRow = wks.UsedRange.Rows.Count
With ActiveWorkbook.Sheets(1)
.Unprotect
lastcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
.Range("A1").Resize(79, lastcol).Sort Key1:=Range("B1"), _
Order1:=xlAscending, _
Header:=xlGuess, _
OrderCustom:=1, _
MatchCase:=False, _
Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End With
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Your code removes duplicates that are one after another. Those duplicates don't touch, thus aren't deleted.
This way of doing is faster (linear and not quadratic like normal duplicate finding code) but does not work if some duplicates don't touch)
Solution : You should sort the table (with regard to all columns, not just the first one) before running the code. This way duplicates will always touch.
Hi all I hope you can help. I have a piece of code see below.
What I am trying to achieve is that a user opens up an Excel sheet that contains a command button and instructions.
Once the command button is clicked a dialog box opens up which then allows the user to select another excel sheet, once that excel sheet is selected another piece of code (should) fire and duplicates are consolidated and start dates and end dates are amended, and the sheet is left open in its desired state free of duplicates and dates correct.
The piece of code
Public Sub ConsolidateDupes()
works perfectly when it is run by itself, on the original sheet but when I try to call it with the command button , its is not working correctly. No error appears it just does not remove all the possible duplicates and does not work the dates to the earliest start and latest end date
I have added pictures to make explanation easier
Pic 1
Excel sheet with Command Button
Pic 2 the Sheet to be selected in its original state with Duplicates and multiple start and end dates
The selected sheet after code has been run by itslef on that sheet
The selected sheet when it is called when command button is used
As you can hopefully see the Duplicates are left and the dates are not worked to the earliest start date and latest end date
As i said the code works perfectly when run on the sheet by itself but when it is called it leaves duplicates and is not working the start and end dates
Here is my code any help is as always greatly appreciated.
CODE
Sub Open_Workbook_Dialog()
Dim my_FileName As Variant
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
If my_FileName <> False Then
Workbooks.Open Filename:=my_FileName
Call ConsolidateDupes '<--|Calls the Filter Code and executes
End If
End Sub
Public Sub ConsolidateDupes()
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
Set wks = Sheet1
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Can you delete this:
Rows(r).Delete
And write this instead:
wks.Rows(r).Delete
Edit:
Try this:
(very dirty solution, but it should work)
Sub Open_Workbook_Dialog()
Dim strFileName As string
dim wkb as workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
set wkb = Application.Workbooks.Open(strFileName)
Set wks = wkb.Sheet1
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
However, the problem is that it did not work, because you did not pass the my_FileName to the ConsolidateDupes procedure. Thus, the procedure was executing in the file with the button, and it was a bit meaningless there.
Hi so some changes were need to get this to work and the code that works is below I hope it helps a fellow VBA'r out :-)
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim LastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
LastRow = wks.UsedRange.Rows.Count
' Sort the B Column Alphabetically
With ActiveWorkbook.Sheets(1)
Dim LastRow2 As Long
LastRow2 = .Cells(Rows.Count, 1).End(xlUp).Row
Dim LastCol As Long
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SortFields.Clear
.SortFields.Add Key:=Range(Cells(2, 2), Cells(LastRow, 2)), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
.SetRange Range(Cells(2, 1), Cells(LastRow, LastCol))
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
For r = LastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
I have a table in a word document that I need to extract only the numbers from. There are 2 cells in the document and the first one has the following string in it:
"24.00 (Hour(s))"
I just need the number "24" from that. It won't always be 2 digits since it's a duration of hours. It may be over 100. It's normally in that format "xxx.xxx" though.
The second cell I need to extract from is a bit more difficult. It looks like this:
"$125.00 to $140.00 per hour"
I would need to extract "125" and place it in a cell in excel and then extract "140" and place it in another cell. These number will always be between "$" and ".00" separated by the word "to".
The duration needs to go into column J and the rates need to be separated into column K & L.
Here is my current code:
Sub ImportWordTable()
Dim wdDoc As Object
Dim wdFileName As Variant
Dim TableNo As Integer 'table number in Word
Dim iTable As Integer 'table number index
Dim iRow As Long 'row index in Excel
Dim iCol As Integer 'column index in Excel
wdFileName = Application.GetOpenFilename("Word files (*.docx),*.docx", , _
"Browse for file containing table to be imported")
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set wdDoc = GetObject(wdFileName) 'open Word file
Worksheets("Request Detail").Activate 'activates sheet of specific name
With wdDoc
TableNo = wdDoc.tables.Count
If TableNo = 0 Then
MsgBox "This document contains no tables", _
vbExclamation, "Import Word Table"
ElseIf TableNo > 1 Then
TableNo = InputBox("This Word document contains " & TableNo & " tables." & vbCrLf & _
"Enter table number of table to import", "Import Word Table", "1")
End If
For iTable = 1 To TableNo
Dim lRow As Long
lRow = Range("A" & Rows.Count).End(xlUp).Offset(1).Row + 1
With .tables(TableNo)
Cells(lRow - 1, "A") = WorksheetFunction.Clean(.cell(14, 2).Range.Text) 'polaris id
Cells(lRow - 1, "B").Value = Date 'post current date
Cells(lRow - 1, "C") = WorksheetFunction.Clean(.cell(16, 2).Range.Text) 'resource manager name
Cells(lRow - 1, "D") = WorksheetFunction.Clean(.cell(15, 2).Range.Text) 'requestor name
Cells(lRow - 1, "E") = WorksheetFunction.Clean(.cell(1, 2).Range.Text) 'customer name
Cells(lRow - 1, "H") = WorksheetFunction.Clean(.cell(7, 2).Range.Text) 'start date
Cells(lRow - 1, "I") = WorksheetFunction.Clean(.cell(8, 2).Range.Text) 'end date
Cells(lRow - 1, "J") = WorksheetFunction.Clean(.cell(9, 2).Range.Text) 'duration
Cells(lRow - 1, "K") = WorksheetFunction.Clean(.cell(12, 2).Range.Text) 'request low rate
Cells(lRow - 1, "L") = WorksheetFunction.Clean(.cell(12, 2).Range.Text) 'request high rate
'Cells(lRow - 1, "S") = WorksheetFunction.Clean(.cell(3, 2).Range.Text) need to post name of negotiatoe
End With
Next iTable
End With
Set wdDoc = Nothing
End Sub
Here is an example of the table parts I'm referring to:
Try this UDF and modify to suit your need. It returns a negative one (-1) if there isn't a match for the N'th number in a line of text.
Assuming the text in Word cell has been put into an Excel range (say C3), Hours stored in column D, Rate min in column E, Rate max in column F, then Formulas in:
D3: =GetNthNumber(C3)
E3: =GetNthNumber(C3,1)
F3: =GetNthNumber(C3,2)
You can do more if line of text contains "days" for the Time.
Option Explicit
Function GetNthNumber(oItem As Variant, Optional Nth As Long) As Double
Dim sText As String, n As Long, i As Long, oTmp As Variant
n = Nth
' Set to First if argument "Nth" is not passed in
If n <= 0 Then n = 1
' Retrieve the text from the input item
Select Case TypeName(oItem)
Case "Range": sText = oItem.Text
Case "String": sText = oItem
Case Else: sText = CStr(oItem)
End Select
i = 0 ' Initialize counter
' Loop through all the words in the text
For Each oTmp In Split(sText, " ")
' Process only if the word is a number
If IsNumeric(oTmp) Then
i = i + 1
' Check if it's the Nth number
If i = n Then
sText = oTmp
Exit For
End If
End If
Next
' Return -1 if there isn't an answer
If Not IsNumeric(sText) Then sText = "-1"
GetNthNumber = CDbl(sText)
End Function
UPDATE
For what you are interested in, first paste in my code above, on a new Module or bottom of your existing code, then change a few lines within the With .tables(TableNo) block to below:
Cells(lRow - 1, "J").Value = GetNthNumber(WorksheetFunction.Clean(.cell(9, 2).Range.Text)) 'duration (Time to Book?)
Cells(lRow - 1, "K").Value = GetNthNumber(WorksheetFunction.Clean(.cell(12, 2).Range.Text), 1) 'request low rate
Cells(lRow - 1, "L").Value = GetNthNumber(WorksheetFunction.Clean(.cell(12, 2).Range.Text), 2) 'request high rate
I received many Excel files from a client.
Their system extracted the data into a spreadsheet, but one column is having issues. If the text was too long, it would put the remaining text into the cell below it.
This causes all the other fields in that row to be blank, except for the overflow.
How can I merge cells at issue into one for all files I received?
I uploaded a screen shot of the file as an example. Notice on row 8 that H8 is the only cell. That needs to be merged with H7. Not every row is at issue though.
asuming A is the main (and empty for doubles)
asuming H holds the text
then in L1 and copy down
=H1&IF(LEN(A2),H2,"")
simplest way (then copy values from L to H and delete empty lines (simply with filter)
when having unknown number of lines (after splitting) you better use vba (or simply repeat the whole procedure till there no empty lines anymore...
doing it in VBA:
Sub testing()
Dim i As Long
While Len(Cells(i + 1, 8))
i = i + 1
While Len(Cells(i + 1, 1)) = 0 And Len(Cells(i + 1, 8))
Cells(i, 8) = Cells(i, 8) & Cells(i + 1, 8)
Rows(i + 1).Delete
Wend
Wend
End Sub
most programs skip spaces so you may want to use:
=H1&IF(LEN(A2)," "&H2,"")
or for vba change Cells(i, 8) = Cells(i, 8) & Cells(i + 1, 8) to Cells(i, 8) = Cells(i, 8) & " " & Cells(i + 1, 8)
This will concatenate the texts in H and delete the row that is not useful :
Sub test_bm11()
Dim wS As Worksheet, _
LastRow As Long, _
i As Long
Set wS = ActiveSheet
With wS
LastRow = .Range("H" & .Rows.Count).End(xlUp).Row
For i = LastRow To 2 Step -1
If .Cells(i, "A") <> vbNullString Then
Else
.Cells(i, "H").Offset(-1, 0) = .Cells(i, "H").Offset(-1, 0) & .Cells(i, "H")
.Cells(i, "H").EntireRow.Delete
End If
Next i
End With
End Sub