It seemed to me that the macro will do this task better than the built-in tools of Calc. Here is the code that (I think) does the job:
Sub combimeData
Const MAIN_SHEET_NAME = "TAB 1"
Const CHILD_SHEET_NAME = "TAB 2"
Const MATCH_COLUMN_NUMBER = 1 ' Column B
Dim oSheets As Variant, oSheet As Variant
Dim oCursor As Variant, oRange As Variant
Dim oSearchDescriptor As Variant, oFound As Variant
Dim aIndex As Variant
Dim oRangeAddressMain As New com.sun.star.table.CellRangeAddress
Dim oRangeAddressChild As New com.sun.star.table.CellRangeAddress
Dim oTargetCellAddress As New com.sun.star.table.CellAddress
Dim i As Long, j As Long, nRow As Long
Dim sNewSheetName As String
oSheets = ThisComponent.getSheets()
Rem Are the names for the data sheets correct?
If Not oSheets.hasByName(MAIN_SHEET_NAME) Then
MsgBox("Sheet " & MAIN_SHEET_NAME & " with Main data not found.", MB_ICONSTOP, " Check sheet name.")
Exit Sub
EndIf
If Not oSheets.hasByName(CHILD_SHEET_NAME) Then
MsgBox("Sheet " & CHILD_SHEET_NAME & " with child subdata not found.", MB_ICONSTOP, " Check sheet name.")
Exit Sub
EndIf
Rem We do not spoil the original data - the macro result will be placed in a new sheet
sNewSheetName = "Result_" & Replace(Replace(Time(),":","_")," ","_")
If oSheets.hasByName(sNewSheetName) Then oSheets.removeByName(sNewSheetName)
oSheets.insertNewByName(sNewSheetName,oSheets.getCount())
Rem Where is the main data located?
oSheet = oSheets.getByName(MAIN_SHEET_NAME)
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
oRangeAddressMain = oCursor.getRangeAddress()
nRow = oRangeAddressMain.EndRow + 1
Rem Get a list of keywords to search
oRange = oSheet.getCellRangeByPosition(MATCH_COLUMN_NUMBER,0,MATCH_COLUMN_NUMBER+2,nRow)
aIndex = oRange.getDataArray()
Rem Where is the additional data?
oSheet = oSheets.getByName(CHILD_SHEET_NAME)
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
oRangeAddressChild = oCursor.getRangeAddress()
nRow = oRangeAddressChild.EndRow
aIndex(UBound(aIndex))(1) = nRow + 1
Rem We will not search for keywords throughout the sheet, but only in the specified column
oRange = oSheet.getCellRangeByPosition(MATCH_COLUMN_NUMBER,0,MATCH_COLUMN_NUMBER, nRow)
Rem Find row numbers where keywords are located
oSearchDescriptor = oRange.createSearchDescriptor()
oSearchDescriptor.SearchType = 1
oSearchDescriptor.SearchWords = True
For i = LBound(aIndex) To UBound(aIndex)-1
If Trim(aIndex(i)(0)) = "" Then
aIndex(i)(1) = -1
Else
oSearchDescriptor.setSearchString(aIndex(i)(0))
oFound = oRange.findFirst(oSearchDescriptor)
If IsNull(oFound) Then
aIndex(i)(1) = -1
Else
aIndex(i)(1) = oFound.getCellAddress().Row
EndIf
EndIf
Next i
Rem Find (calculate) the last row numbers for each subrange
For i = LBound(aIndex) To UBound(aIndex)-1
If aIndex(i)(1) >= 0 Then
nRow = aIndex(UBound(aIndex))(1)
For j = LBound(aIndex) To UBound(aIndex)
If aIndex(j)(1) > aIndex(i)(1) Then
If aIndex(j)(1) < nRow Then
nRow = aIndex(j)(1) - 1
EndIf
EndIf
Next j
aIndex(i)(2) = nRow
EndIf
Next i
Rem Copy data to result sheet
oSheet = oSheets.getByName(sNewSheetName)
oTargetCellAddress = oSheet.getCellByPosition(0, 0).getCellAddress()
nRow = oTargetCellAddress.Row
Rem Copy every row from main sheet
For i = LBound(aIndex) To UBound(aIndex)-1
oRangeAddressMain.StartRow = i
oRangeAddressMain.EndRow = i
oSheet.copyRange(oTargetCellAddress, oRangeAddressMain)
oTargetCellAddress.Row = oTargetCellAddress.Row + 1
Rem If required, add (copy) the range from the child sheet
If aIndex(i)(1) >= 0 Then
oRangeAddressChild.StartRow = aIndex(i)(1)+1
oRangeAddressChild.EndRow = aIndex(i)(2)
oSheet.copyRange(oTargetCellAddress, oRangeAddressChild)
oTargetCellAddress.Row = oTargetCellAddress.Row + aIndex(i)(2) - aIndex(i)(1)
EndIf
Next i
Rem Set the optimal column width
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
oCursor.getColumns().OptimalWidth = True
Rem Activate result sheet
With ThisComponent.getCurrentController()
.Select(oSheet.getCellByPosition(0,0))
.Select(ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges"))
End With
End Sub
Tab 1 contains a button that will execute this code - CALC exemple macro.ods (25.5 KB)
Please don’t be surprised that after running the macro for the first time, you don’t get the result you expected. The matter is that for the keyword Subtext 2 there is no corresponding block on the sheet Tab 2. Just fix Ssubtext 2 on the sheet Tab 2 and press the button again. Now you know where to look for the error in the first place if the macro ever gives wrong results.
Please excuse me for the delay in replying. The macro was ready a few hours ago, but I did not have time to publish it - the power went out. As you know, russian terrorists are shelling the energy infrastructure in my country. Thus, these barbarians harm not only me, not only all the inhabitants of Ukraine, but also you and other people around the world whom I could help if our power plants were not bombed.