Как я нарезаю массив в Excel VBA?

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

27
задан Teamothy 4 November 2019 в 22:36
поделиться

3 ответа

Приложение. WorksheetFunction. Индекс (массив, строка, столбец)

при определении нулевого значения для строки или столбца, тогда Вы получите весь столбец или строку, которая определяется.

Пример:

Приложение. WorksheetFunction. Индекс (массив, 0, 3)

Это даст Вам весь 3-й столбец.

при определении и строки и столбца как ненулевых, тогда Вы получите только определенный элемент. Нет никакого простого способа получить меньшую часть, чем полная строка или столбец.

Ограничение : существует предел размеру массива, который WorksheetFunction.Index может обработать, если Вы используете более новую версию Excel. Если array имеет больше чем 65 536 строк или 65 536 столбцов, то это бросает ошибку "Несоответствия типов". Если это - проблема для Вас, то см. этот более сложный ответ , который не подвергается тому же ограничению.

Вот функция, которую я записал, чтобы сделать все мой 1D и 2D разрезание:

Public Function GetArraySlice2D(Sarray As Variant, Stype As String, Sindex As Integer, Sstart As Integer, Sfinish As Integer) As Variant

' this function returns a slice of an array, Stype is either row or column
' Sstart is beginning of slice, Sfinish is end of slice (Sfinish = 0 means entire
' row or column is taken), Sindex is the row or column to be sliced
' (NOTE: 1 is always the first row or first column)
' an Sindex value of 0 means that the array is one dimensional 3/20/09 ljr

Dim vtemp() As Variant
Dim i As Integer

On Err GoTo ErrHandler

Select Case Sindex
    Case 0
        If Sfinish - Sstart = UBound(Sarray) - LBound(Sarray) Then
            vtemp = Sarray
        Else
            ReDim vtemp(1 To Sfinish - Sstart + 1)
            For i = 1 To Sfinish - Sstart + 1
                vtemp(i) = Sarray(i + Sstart - 1)
            Next i
        End If
    Case Else
        Select Case Stype
            Case "row"
                If Sfinish = 0 Or (Sstart = LBound(Sarray, 2) And Sfinish = UBound(Sarray, 2)) Then
                    vtemp = Application.WorksheetFunction.Index(Sarray, Sindex, 0)
                Else
                    ReDim vtemp(1 To Sfinish - Sstart + 1)
                    For i = 1 To Sfinish - Sstart + 1
                        vtemp(i) = Sarray(Sindex, i + Sstart - 1)
                    Next i
                End If
            Case "column"
                If Sfinish = 0 Or (Sstart = LBound(Sarray, 1) And Sfinish = UBound(Sarray, 1)) Then
                    vtemp = Application.WorksheetFunction.Index(Sarray, 0, Sindex)
                Else
                    ReDim vtemp(1 To Sfinish - Sstart + 1)
                    For i = 1 To Sfinish - Sstart + 1
                        vtemp(i) = Sarray(i + Sstart - 1, Sindex)
                    Next i
                End If
        End Select
End Select
GetArraySlice2D = vtemp
Exit Function

ErrHandler:
    Dim M As Integer
    M = MsgBox("Bad Array Input", vbOKOnly, "GetArraySlice2D")

End Function
53
ответ дан Community 28 November 2019 в 04:19
поделиться

Можно использовать комбинацию строк, Столбцов, свойств Offset и Resize для получения подмножества диапазона.

, Например, если у Вас есть диапазон, который составляет 5 столбцов 3 строками:

Set rng = Range("A1:E3")

можно получить любое подмножество путем соответствующего комбинирования вышеупомянутых свойств. Например, если Вы хотите получить самые правые 3 ячейки на второй строке (т.е. "C2:E2" в вышеупомянутом примере), Вы могли сделать что-то как:

   Set rngSubset = rng.Rows(2).Offset(0, rng.Columns.Count - 3).Resize(1, 3)

Вы могли тогда обернуть это в функции VBA.

1
ответ дан Joe 28 November 2019 в 04:19
поделиться

Две вещи: VBA не поддерживает нарезку массивов, поэтому, что бы вы ни использовали, вам придется использовать собственное. Но поскольку это только для Excel, вы можете использовать функцию построения в листе индекса функции для нарезки массива.

Sub Test()
    'All example return a 1 based 2D array.
    Dim myArr As Variant 'This var must be generic to work.
    'Get whole range:
    myArr = ActiveSheet.UsedRange
    'Get just column 1:
    myArr = WorksheetFunction.Index(ActiveSheet.UsedRange, 0, 1)
    'Get just row 5
    myArr = WorksheetFunction.Index(ActiveSheet.UsedRange, 5, 0)
End Sub
4
ответ дан 28 November 2019 в 04:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: