There's no need to iterate twice, first through cells and then through array.
You can make it in one iteration like this:
Option Explicit
Sub main()
Dim i As Long, lastRow As Long, nonBlankCellsNumber As Long
Dim QB_Thema As Long, QB_StartCell As Long
Dim cell As Range
Dim topicArr() As String, subTopicArr() As String
QB_Thema = 3 'added this for my test
QB_StartCell = 4
lastRow = GetLastRow(Worksheets("QB"), QB_Thema, "F", QB_StartCell) '<== I assumed as per your code that you stop at the first occurrence of a blank cell. should you want to process all non blank data to the last non blank cell, then use "L" as the 3rd argument of this call
If lastRow = -1 Then Exit Sub
With Worksheets("QB")
With .Range(.Cells(QB_StartCell, QB_Thema), .Cells(lastRow, QB_Thema))
nonBlankCellsNumber = WorksheetFunction.CountA(.Cells)
ReDim topicArr(1 To nonBlankCellsNumber)
ReDim subTopicArr(1 To nonBlankCellsNumber)
i = 0
For Each cell In .Cells.SpecialCells(xlCellTypeConstants, xlTextValues)
i = i + 1
topicArr(i) = Split(cell.value, "/")(0)
subTopicArr(i) = Split(cell.value, "/")(1)
Next cell
End With
End With
End Sub
Function GetLastRow(sht As Worksheet, columnIndex As Long, FirstOrLastBlank As String, Optional firstRow As Variant) As Long
If IsMissing(firstRow) Then firstRow = 1
With sht
If FirstOrLastBlank = "F" Then
With .Cells(firstRow, columnIndex)
If .value = "" Then
GetLastRow = .End(xlDown).End(xlDown).row
Else
GetLastRow = .End(xlDown).row
End If
End With
If GetLastRow = .Rows.count And .Cells(GetLastRow, columnIndex) = "" Then GetLastRow = firstRow
ElseIf FirstOrLastBlank = "F" Then
GetLastRow = .Cells(.Rows.count, columnIndex).End(xlUp).row
If GetLastRow < firstRow Then GetLastRow = firstRow
Else
MsgBox "invalid 'FirstOrLastBlank' parameter"
GetLastRow = -1
End If
End With
End Function
As you see I also posted Function GetLastRow() to get the last row index of data to scan.
As per your code I got you want to start at row 4 and stop at the first blank cell (excluded), and so I tuned the arguments (namely the 3rd one: "F") in the call to GetLastRow accordingly.
Instead, should you want to scan all non-blank cells in the given column, then you may call the same GetLastRow function passing "L" as 3rd parameter.
sepearate(0)will give you theTopicandsepearate(1)will give you theSubtopicalso in the last Do Loop you are not incrementing or decrementing thep