При чтении csv в строку он содержит нулевое значение между строкой, поэтому попробуйте его \ 0 Строка за строкой работает.
stringLine = stringLine.replace( /\0/g, "" );
Порядок, в котором For Each
выполняет итерацию коллекции объектов, зависит от реализации (я обвиняю Excel, а не VBA) и, хотя и, вероятно, детерминирован & amp; предсказуемо, в его спецификации нет ничего, что гарантировало бы определенный порядок итераций. Поэтому код VBA, написанный для итерации коллекции объектов, не должен быть написан с предположением о конкретном порядке итерации, поскольку это то, что может очень хорошо меняться в зависимости от версии используемой библиотеки типов (в данном случае Excel).
Очень неясно, какова форма ваших Range
/ Selection
, но если вам нужно перебрать выбранные ячейки в определенном порядке, то цикл For Each
не должен использоваться, по крайней мере, не для перебора. клетки как таковые.
Так как диапазоны не являются смежными, Range
будет иметь кратные Areas
; вам нужно будет выполнить итерации Selection.Areas
и для каждой выбранной области, итерировать ячейки в определенном порядке. For Each
, безусловно, является наиболее эффективным способом итерации коллекции объектов , которой является Range.Areas
.
Debug.Assert TypeOf Selection Is Excel.Range
Dim currentArea As Range
For Each currentArea In Selection.Areas
'todo
Next
Вместо того, чтобы вкладывать циклы , создайте отдельную процедуру, которая принимает currentArea
в качестве параметра - в этой процедуре вы будете повторять отдельные ячейки:
Теперь внешний цикл выглядит следующим образом:
Debug.Assert TypeOf Selection Is Excel.Range
Dim currentArea As Range
For Each currentArea In Selection.Areas
ProcessContiguousArea currentArea
Next
Процедура ProcessContiguousArea
свободна делать все, что нужно, с данной смежной областью, используя цикл For
для итерации диапазон по строкам без необходимости заботиться о фактическом адресе выбранной области: при использовании Range.Cells(RowIndex, ColumnIndex)
строка 1 / столбец 1 представляет верхнюю левую ячейку этого диапазона, независимо от того, где этот диапазон находится на рабочем листе. [1130 ]
Невыбранные ячейки могут быть доступны с помощью Range.Offset
:
Debug.Print area.Cells(currentRow, 1).Offset(ColumnOffset:=10).Address
Строка верхней левой ячейки area
на рабочем листе возвращается с помощью area.Row
, а верхняя левая Столбец ячейки area
на рабочем листе извлекается с помощью area.Column
.
Это основано на предложении urdearboy:
1. цикл по столбцам
2. внутри столбца, цикл по ячейкам
[117 ]
Sub disjoint()
Dim r As Range, rInt As Range
Dim nLastColumn As Long
Dim nFirstColumn As Long, msg As String
Dim N As Long
Set r = Range("C3,C9,E6,E13,E15,G1,G2,G3,G4")
nFirstColumn = Columns.Count
nLastColumn = 0
msg = ""
For Each rr In r
N = rr.Column
If N < nFirstColumn Then nFirstColumn = N
If N > nLastColumn Then nLastColumn = N
Next rr
For N = nFirstColumn To nLastColumn
Set rInt = Intersect(Columns(N), r)
If rInt Is Nothing Then
Else
For Each rr In rInt
msg = msg & vbCrLf & rr.Address(0, 0)
Next rr
End If
Next N
MsgBox msg
End Sub
Зацикливая сначала рядов ( i ), вы получите последовательность By Row ', например А1, В1, С1, ...
Sub NonContiguous()
Dim i As Long
Dim j As Long
Dim k As Long
With Selection
For k = 1 To .Areas.Count
With .Areas(k)
For i = .Row To .Rows.Count + .Row - 1
For j = .Column To .Columns.Count + .Column - 1
Debug.Print .Parent.Cells(i, j).Address & " = " _
& .Parent.Cells(i, j)
Next
Next
End With
Next
End With
End Sub