VBA의 범위에서 어레이 생성
겉보기에는 기본적인 문제가 있지만 해결할 리소스를 찾을 수 없습니다.
간단히 말해, 셀 범위(모두 하나의 열)의 내용을 배열로 로드하려고 합니다.
저는 이 일을 할 수 있습니다.
DirArray = Array(Range("A1"), Range("A2"))
그러나 다음과 같이 표현하면 어떤 이유에서인지 배열을 만들 수 없습니다.
DirArray = Array(Range("A1:A2"))
실제 범위가 훨씬 길기 때문에 이러한 방식으로 셀을 개별적으로 열거할 필요가 없습니다.전체 범위를 배열로 올바르게 로드하는 방법을 알려줄 수 있는 사람이 있습니까?
후자 코드의 경우:
MsgBox UBound(DirArray, 1)
그리고.
MsgBox UBound(DirArray)
0을 반환하고 전자는 1을 반환합니다.
변수를 변수로 정의하고 다음과 같이 동일하게 만듭니다.
Dim DirArray As Variant
DirArray = Range("a1:a5").Value
배열 명령이 필요 없습니다.
이렇게 하면 다음과 같습니다.
Dim myArr as Variant
myArr = Range("A1:A10")
새 배열은 2차원이 될 것입니다.다음과 같이 작업하기에 항상 편안한 것은 아닙니다.
2차원에서 벗어나기 위해 단일 열을 배열로 가져올 때 내장된 Excel 함수 "Transpose"를 사용할 수 있습니다.그러면 데이터가 다음과 같이 한 차원으로 이동합니다.
만약 우리가 데이터를 연속적으로 가지고 있다면, 한 번의 전치는 그 일을 할 수 없을 것입니다.Transpose(전환) 기능을 두 번 사용해야 합니다.
참고: 스크린샷에서 볼 수 있듯이 이러한 방식으로 생성되면 배열이 0이 아닌 1로 시작됩니다.조금만 조심하세요.
6월 편집.2021: 최신 버전의 Excel에서 기능은 다음과 같습니다.Application.WorksheetFunction.Transpose()
용사를 합니다.Value2
성능 이점을 제공합니다.찰스 윌리엄스 블로그에 따르면
Range.Value2는 Range와 동일한 방식으로 작동합니다.셀 형식을 확인하고 날짜 또는 통화로 변환하지 않는 것을 제외한 값입니다.그리고 그것이 아마도 그것보다 더 빠른 이유일 것입니다.숫자를 검색할 때 값입니다.
그렇게
DirArray = [a1:a5].Value2
보너스 판독치
- Range.Value: 지정한 범위의 값을 나타내는 Variant 값을 반환하거나 설정합니다.
- 범위.값 2:이 속성과 Value 속성의 유일한 차이점은 Value2 속성이 통화 및 날짜 데이터 유형을 사용하지 않는다는 것입니다.
이 함수는 범위의 크기에 관계없이 배열을 반환합니다.
범위가 1 셀이 아니면 배열을 반환하고 대신 단일 값을 반환합니다.이 함수는 단일 값을 배열로 변환합니다(1 기반, 범위별로 반환되는 배열과 동일).
이 답변은 크기에 관계없이 범위에서 배열을 반환하므로 이전 답변보다 향상되었습니다.또한 가능하면 범위에서 생성된 배열을 반환하므로 다른 답변보다 효율적입니다.단일 차원 및 다차원 어레이와 함께 작동
함수는 배열의 상한을 찾음으로써 작동합니다.실패할 경우 단일 값이어야 하므로 어레이를 생성하고 이 값을 할당합니다.
Public Function RangeToArray(inputRange As Range) As Variant()
Dim size As Integer
Dim inputValue As Variant, outputArray() As Variant
' inputValue will either be an variant array for ranges with more than 1 cell
' or a single variant value for range will only 1 cell
inputValue = inputRange
On Error Resume Next
size = UBound(inputValue)
If Err.Number = 0 Then
RangeToArray = inputValue
Else
On Error GoTo 0
ReDim outputArray(1 To 1, 1 to 1)
outputArray(1,1) = inputValue
RangeToArray = outputArray
End If
On Error GoTo 0
End Function
제안된 솔루션 외에 1D 범위에서 1D 어레이를 사용하는 경우 아래와 같은 기능을 통해 처리하는 것을 선호합니다.이유는 간단합니다. 어떤 이유로든 범위가 1개의 요소 범위로 줄어든 경우 Range() 명령을 알고 있습니다.값은 변형 배열을 반환하지 않고 변형만 반환하며, 변형 배열(이전에 선언됨)에 변형 변수를 할당할 수 없습니다.
저는 가변 크기 범위를 이중 배열로 변환해야 했고, 범위가 1 셀 크기일 때는 range(.value)와 같은 구성을 사용할 수 없어서 아래와 같은 함수로 진행합니다.
Public Function Rng2Array(inputRange As Range) As Double()
Dim out() As Double
ReDim out(inputRange.Columns.Count - 1)
Dim cell As Range
Dim i As Long
For i = 0 To inputRange.Columns.Count - 1
out(i) = inputRange(1, i + 1) 'loop over a range "row"
Next
Rng2Array = out
End Function
저는 범위 내의 세포들을 반복하는 것에 대한 또 다른 투표입니다.누군가 해결책을 찾지 못한 경우를 제외하고 Variant에 범위를 직접 할당하려고 시도한 경험은 내 범위에 여러 영역이 있는 경우(예: 필터링된 테이블의 열에 보이는 셀만 원하는 경우)를 제외하고는 잘 작동한다는 것입니다.또는 Ctrl 키를 누른 상태에서 시트에 있는 여러 개의 셀 블록을 선택한 경우.
범위의 모든 셀을 에 대해 반복합니다.각각의 루프는 항상 제가 기대하는 결과를 만들어냅니다.
Public Function RangeToArray(ByRef myRange As Range)
Dim i As Long
Dim individualCell As Range
ReDim myArray(myRange.Count - 1)
For Each individualCell In myRange
myArray(i) = individualCell.Text ' or maybe .Value
i = i + 1
Next
RangeToArray = myArray
End Function
저는 파올로의 답변과 비슷하지만 저는 신인이고 충분한 평판을 가지고 있지 않기 때문에 이것을 코멘트로 추가하고 싶었습니다. 그래서 여기 약간 다른 답변이 있습니다.
@Vityata의 답변에 추가하여, 아래는 1D 배열에서 행/열 벡터를 변환하는 데 사용하는 함수입니다.
Function convertVecToArr(ByVal rng As Range) As Variant
'convert two dimension array into a one dimension array
Dim arr() As Variant, slicedArr() As Variant
arr = rng.value 'arr = rng works too (https://bettersolutions.com/excel/cells-ranges/vba-working-with-arrays.htm)
If UBound(arr, 1) > UBound(arr, 2) Then
slicedArr = Application.WorksheetFunction.Transpose(arr)
Else
slicedArr = Application.WorksheetFunction.index(arr, 1, 0) 'If you set row_num or column_num to 0 (zero), Index returns the array of values for the entire column or row, respectively._
'To use values returned as an array, enter the Index function as an array formula in a horizontal range of cells for a row,_
'and in a vertical range of cells for a column.
'https://usefulgyaan.wordpress.com/2013/06/12/vba-trick-of-the-week-slicing-an-array-without-loop-application-index/
End If
convertVecToArr = slicedArr
End Function
전치병은 좋은 조언입니다.앱에 여러 개의 어레이가 있습니다.일부는 전역, 일부는 로컬, 일부는 범위에서 로드되고 일부는 프로그래밍 방식으로 생성됩니다.
치수를 재는 데 많은 문제가 있었습니다.자, 전치수를 사용하면 모두 한 차원이 됩니다.
한 버전은 Excel 2003에서 실행되고 다른 버전은 2010에서 실행되기 때문에 코드를 약간 수정해야 했습니다.
주의:배열을 범위에 저장할 때 배열을 다시 전치해야 합니다.
범위 모양 사용
다음을 위한 기능을 만드는 또 다른 접근 방식ArrayFromRange
범위의 모양과 크기를 사용하여 배열을 구성하는 방법을 결정합니다.이렇게 하면 치수를 결정하기 위해 데이터를 중간 배열에 로드할 필요가 없습니다.
를 들어,셀만인 이 포함된 해야 합니다.Array(target.value)
.
아래는 모든 경우를 처리해야 하는 전체 기능입니다.이 방법은 배열 모양을 변경하는 데 사용되는 것과 동일한 방법을 사용합니다.
' Helper function that returns an array from a range with the
' correct dimensions. This fixes the issue of single values
' not returning as an array, and when a 2 dimension array is returned
' when it only has 1 dimension of data.
'
' @author Robert Todar <robert@roberttodar.com>
Public Function ArrayFromRange(ByVal target As Range) As Variant
Select Case True
' Single cell
Case target.Cells.Count = 1
ArrayFromRange = Array(target.Value)
' Single Row
Case target.Rows.Count = 1
ArrayFromRange = Application.Transpose( _
Application.Transpose(target.Value) _
)
' Single Column
Case target.Columns.Count = 1
ArrayFromRange = Application.Transpose(target.Value)
' Multi dimension array
Case Else
ArrayFromRange = target.Value
End Select
End Function
『 』 ArrayFromRange
를 수행
보너스로, 이 기능이 작동하는지 확인하기 위해 실행한 테스트가 있습니다.
' @requires {function} ArrayDimensionLength
' @requires {function} ArrayCount
Private Sub testArrayFromRange()
' Setup a new workbook/worksheet for
' adding testing data
Dim testWorkbook As Workbook
Set testWorkbook = Workbooks.Add
Dim ws As Worksheet
Set ws = testWorkbook.Worksheets(1)
' Add sample data for testing.
ws.Range("A1:A2") = Application.Transpose(Array("A1", "A2"))
ws.Range("B1:B2") = Application.Transpose(Array("B1", "B2"))
' This section will run all the tests.
Dim x As Variant
' Single cell
x = ArrayFromRange(ws.Range("A1"))
Debug.Assert ArrayDimensionLength(x) = 1
Debug.Assert ArrayCount(x) = 1
' Single Row
x = ArrayFromRange(ws.Range("A1:B1"))
Debug.Assert ArrayDimensionLength(x) = 1
Debug.Assert ArrayCount(x) = 2
' Single Column
x = ArrayFromRange(ws.Range("A1:A2"))
Debug.Assert ArrayDimensionLength(x) = 1
Debug.Assert ArrayCount(x) = 2
' Multi Column
x = ArrayFromRange(ws.Range("A1:B2"))
Debug.Assert ArrayDimensionLength(x) = 2
Debug.Assert ArrayCount(x) = 4
' Cleanup testing environment
testWorkbook.Close False
' Print result
Debug.Print "testArrayFromRange: PASS"
End Sub
테스트 도우미 기능
는 두 기능을 했습니다: 테트에두가도기사능용다니습했을미우스서지:다.ArrayCount
,그리고.ArrayDimensionLength
이러한 항목은 아래에 참조용으로 나열되어 있습니다.
' Returns the length of the dimension of an array
'
' @author Robert Todar <robert@roberttodar.com>
Public Function ArrayDimensionLength(sourceArray As Variant) As Integer
On Error GoTo catch
Do
Dim currentDimension As Long
currentDimension = currentDimension + 1
' `test` is used to see when the
' Ubound throws an error. It is unused
' on purpose.
Dim test As Long
test = UBound(sourceArray, currentDimension)
Loop
catch:
' Need to subtract one because the last
' one errored out.
ArrayDimensionLength = currentDimension - 1
End Function
' Get count of elements in an array regardless of
' the option base. This Looks purely at the size
' of the array, not the contents within them such as
' empty elements.
'
' @author Robert Todar <robert@roberttodar.com>
' @requires {function} ArrayDimensionLength
Public Function ArrayCount(ByVal sourceArray As Variant) As Long
Dim dimensions As Long
dimensions = ArrayDimensionLength(sourceArray)
Select Case dimensions
Case 0
ArrayCount = 0
Case 1
ArrayCount = (UBound(sourceArray, 1) - LBound(sourceArray, 1)) + 1
Case Else
' Need to set arrayCount to 1 otherwise the
' loop will keep multiplying by zero for each
' iteration
ArrayCount = 1
Dim dimension As Long
For dimension = 1 To dimensions
ArrayCount = ArrayCount * _
((UBound(sourceArray, dimension) - LBound(sourceArray, dimension)) + 1)
Next
End Select
End Function
언급URL : https://stackoverflow.com/questions/37689847/creating-an-array-from-a-range-in-vba
'programing' 카테고리의 다른 글
루비에서 예외를 높이는 것과 예외를 던지는 것의 차이점은 무엇입니까? (0) | 2023.06.01 |
---|---|
장고 관리자의 필드 크기 조정 (0) | 2023.05.27 |
Azure 리소스 그룹의 이름을 변경하려면 어떻게 해야 합니까? (0) | 2023.05.27 |
많은 컬렉션을 바인딩하여 WPF ComboBox 성능 문제 (0) | 2023.05.27 |
psql을 사용하여 Postgre에 연결SSL 모드의 SQL (0) | 2023.05.27 |