programing

요소가 특정 값 VBA인 경우 배열에서 요소 삭제

lastmoon 2023. 7. 6. 22:30
반응형

요소가 특정 값 VBA인 경우 배열에서 요소 삭제

전 세계적인 조직을 가지고 있고,prLst()길이가 다양한 캔.로 사용합니다."1"Ubound(prLst)가 그나사가입경력우한자용러경우▁the한,"0"목록에서 해당 요소를 삭제하고 싶습니다.는 이것을과 같은 했습니다.

count2 = 0
eachHdr = 1
totHead = UBound(prLst)

Do
    If prLst(eachHdr) = "0" Then
        prLst(eachHdr).Delete
        count2 = count2 + 1
    End If
    keepTrack = totHead - count2
    'MsgBox "prLst = " & prLst(eachHdr)
    eachHdr = eachHdr + 1
Loop Until eachHdr > keepTrack

이것은 작동하지 않습니다. ?prLst가 약만그렇면인 "0"?


참고: 이 프로그램은 더 큰 프로그램의 일부이며, 설명은 다음에서 찾을 수 있습니다: 행 그룹 정렬 Excel VBA 매크로

배열은 특정 크기를 가진 구조입니다.ReDim을 사용하여 축소하거나 확장할 수 있지만 중간에 요소를 제거할 수 없는 vba의 동적 배열을 사용할 수 있습니다.어레이가 기능적으로 작동하는 방식이나 인덱스 위치(각 HDR)를 결정하는 방법은 샘플에서 명확하지 않지만 기본적으로 3가지 옵션이 있습니다.

어레이에 대한 사용자 지정 '삭제' 함수를 작성합니다(테스트되지 않음).

Public Sub DeleteElementAt(Byval index As Integer, Byref prLst as Variant)
       Dim i As Integer
        
        ' Move all element back one position
        For i = index + 1 To UBound(prLst)
            prLst(i - 1) = prLst(i)
        Next
        
        ' Shrink the array by one, removing the last one
        ReDim Preserve prLst(LBound(prLst) To UBound(prLst) - 1)
End Sub

요소를 실제로 삭제하는 대신 '더미' 값을 값으로 설정하기만 하면 됩니다.

If prLst(eachHdr) = "0" Then        
   prLst(eachHdr) = "n/a"
End If

어레이 사용을 중지하고 VBA로 변경합니다.수집.집합은 요소를 자유롭게 추가하거나 삭제할 수 있는 (고유한) 키/값 쌍 구조입니다.

Dim prLst As New Collection

여기에 다음을 사용하는 코드의 샘플이 있습니다.CopyMemory그 일을 하는 기능.

(어레이의 크기와 유형에 따라) "훨씬 더 빠릅니다.

저는 저자는 아니지만, 그것을 테스트했습니다:

Sub RemoveArrayElement_Str(ByRef AryVar() As String, ByVal RemoveWhich As Long) 

'// The size of the array elements
'// In the case of string arrays, they are
'// simply 32 bit pointers to BSTR's.
Dim byteLen As Byte

'// String pointers are 4 bytes
byteLen = 4

'// The copymemory operation is not necessary unless
'// we are working with an array element that is not
'// at the end of the array
If RemoveWhich < UBound(AryVar) Then
    '// Copy the block of string pointers starting at
    ' the position after the
    '// removed item back one spot.
    CopyMemory ByVal VarPtr(AryVar(RemoveWhich)), ByVal _
        VarPtr(AryVar(RemoveWhich + 1)), (byteLen) * _
        (UBound(AryVar) - RemoveWhich)
End If

'// If we are removing the last array element
'// just deinitialize the array
'// otherwise chop the array down by one.
If UBound(AryVar) = LBound(AryVar) Then
    Erase AryVar
Else
    ReDim Preserve AryVar(LBound(AryVar) To UBound(AryVar) - 1)
End If
End Sub
Sub DelEle(Ary, SameTypeTemp, Index As Integer) '<<<<<<<<< pass only not fixed sized array (i don't know how to declare same type temp array in proceder)
    Dim I As Integer, II As Integer
    II = -1
    If Index < LBound(Ary) And Index > UBound(Ary) Then MsgBox "Error.........."
    For I = 0 To UBound(Ary)
        If I <> Index Then
            II = II + 1
            ReDim Preserve SameTypeTemp(II)
            SameTypeTemp(II) = Ary(I)
        End If
    Next I
    ReDim Ary(UBound(SameTypeTemp))
    Ary = SameTypeTemp
    Erase SameTypeTemp
End Sub

Sub Test()
    Dim a() As Integer, b() As Integer
    ReDim a(3)
    Debug.Print "InputData:"
    For I = 0 To UBound(a)
        a(I) = I
        Debug.Print "    " & a(I)
    Next
    DelEle a, b, 1
    Debug.Print "Result:"
    For I = 0 To UBound(a)
        Debug.Print "    " & a(I)
    Next
End Sub

어레이를 만들 때 0을 건너뛰고 나중에 걱정할 시간을 절약하는 것은 어떻습니까?위에서 언급한 것처럼 어레이는 삭제하기에 적합하지 않습니다.

저는 vba & excel에 익숙하지 않습니다. 약 3개월 동안만 이 작업을 수행했습니다. 이 게시물과 관련이 있어 보이므로 여기에서 어레이 중복 제거 방법을 공유하려고 합니다.

파이프 데이터를 분석하는 대규모 응용 프로그램의 일부인 경우 이 코드는 파이프가 xxxx.1, xxxx.2, yyy.1, yyy.2... 형식의 숫자로 시트에 나열되어 있습니다.그래서 모든 문자열 조작이 존재합니다. 기본적으로 파이프 번호는 한 번만 수집하고 .2 또는 .1 부분은 수집하지 않습니다.

        With wbPreviousSummary.Sheets(1)
'   here, we will write the edited pipe numbers to a collection - then pass the collection to an array
        Dim PipeDict As New Dictionary

        Dim TempArray As Variant

        TempArray = .Range(.Cells(3, 2), .Cells(3, 2).End(xlDown)).Value

        For ele = LBound(TempArray, 1) To UBound(TempArray, 1)

            If Not PipeDict.Exists(Left(TempArray(ele, 1), Len(TempArray(ele, 1) - 2))) Then

                PipeDict.Add Key:=Left(TempArray(ele, 1), Len(TempArray(ele, 1) - 2)), _
                                                        Item:=Left(TempArray(ele, 1), Len(TempArray(ele, 1) - 2))

            End If

        Next ele

        TempArray = PipeDict.Items

        For ele = LBound(TempArray) To UBound(TempArray)
            MsgBox TempArray(ele)
        Next ele

    End With
    wbPreviousSummary.Close SaveChanges:=False

    Set wbPreviousSummary = Nothing 'done early so we dont have the information loaded in memory

ATM 디버깅을 위해 메시지 상자 더미 사용 - 자신의 작업에 맞게 변경할 것임을 확신합니다.

사람들이 이것을 유용하게 생각하길 바랍니다, Joe에게 경의를 표합니다.

요소가 특정 값 VBA인 경우 배열에서 요소 삭제

특정 조건을 가진 배열의 요소를 삭제하려면 다음과 같이 코드화할 수 있습니다.

For i = LBound(ArrValue, 2) To UBound(ArrValue, 2)
    If [Certain condition] Then
        ArrValue(1, i) = "-----------------------"
    End If
Next i

StrTransfer = Replace(Replace(Replace(join(Application.Index(ArrValue(), 1, 0), ","), ",-----------------------,", ",", , , vbBinaryCompare), "-----------------------,", "", , , vbBinaryCompare), ",-----------------------", "", , , vbBinaryCompare)
ResultArray = join( Strtransfer, ",")

조인/분할을 사용하여 1D 어레이를 자주 조작하지만, 다차원에서 특정 값을 삭제해야 하는 경우에는 이와 같이 어레이를 1D 어레이로 변경하는 것이 좋습니다.

strTransfer = Replace(Replace(Replace(Replace(Names.Add("A", MultiDimensionArray), Chr(34), ""), "={", ""), "}", ""), ";", ",")
'somecode to edit Array like 1st code on top of this comment
'then loop through this strTransfer to get right value in right dimension
'with split function.

이것이 오래된 것이라는 것을 알지만, 제가 발견한 것들이 마음에 들지 않았을 때 생각해 낸 해결책이 있습니다.

- 제거할 요소와 일치하지 않는 한 각 요소와 일부 구분 기호를 문자열에 추가하는 배열(변수)을 반복합니다. 그런 다음 구분 기호에서 문자열을 분할합니다.

tmpString=""
For Each arrElem in GlobalArray
   If CStr(arrElem) = "removeThis" Then
      GoTo SkipElem
   Else
      tmpString =tmpString & ":-:" & CStr(arrElem)
   End If
SkipElem:
Next
GlobalArray = Split(tmpString, ":-:")

문자열을 사용하면 배열에 이미 있는 정보를 확인해야 하는 등 몇 가지 제한 사항이 발생합니다. 이 코드를 사용하면 첫 번째 배열 요소가 비어 있지만 필요한 작업을 수행하고 작업을 조금 더 많이 수행하면 더 다양한 용도로 사용할 수 있습니다.

간단합니다.출력 시트의 두 열에서 고유한 값을 가진 문자열을 얻기 위해 다음과 같은 방법을 사용했습니다.

Dim startpoint, endpoint, ArrCount As Integer
Dim SentToArr() As String

'created by running the first part (check for new entries)
startpoint = ThisWorkbook.Sheets("temp").Range("A1").Value
'set counter on 0
Arrcount = 0 
'last filled row in BG
endpoint = ThisWorkbook.Sheets("BG").Range("G1047854").End(xlUp).Row

'create arr with all data - this could be any data you want!
With ThisWorkbook.Sheets("BG")
    For i = startpoint To endpoint
        ArrCount = ArrCount + 1
        ReDim Preserve SentToArr(1 To ArrCount)
        SentToArr(ArrCount) = .Range("A" & i).Value
        'get prep
        ArrCount = ArrCount + 1
        ReDim Preserve SentToArr(1 To ArrCount)
        SentToArr(ArrCount) = .Range("B" & i).Value
    Next i
End With

'iterate the arr and get a key (l) in each iteration
For l = LBound(SentToArr) To UBound(SentToArr)
    Key = SentToArr(l)
    'iterate one more time and compare the first key (l) with key (k)
    For k = LBound(SentToArr) To UBound(SentToArr)
        'if key = the new key from the second iteration and the position is different fill it as empty
        If Key = SentToArr(k) And Not k = l Then
            SentToArr(k) = ""
        End If
    Next k
Next l

'iterate through all 'unique-made' values, if the value of the pos is 
'empty, skip - you could also create a new array by using the following after the IF below - !! dont forget to reset [ArrCount] as well:
'ArrCount = ArrCount + 1
'ReDim Preserve SentToArr(1 To ArrCount)
'SentToArr(ArrCount) = SentToArr(h)

For h = LBound(SentToArr) To UBound(SentToArr)
    If SentToArr(h) = "" Then GoTo skipArrayPart
    GetEmailArray = GetEmailArray & "; " & SentToArr(h)
skipArrayPart:
Next h

'some clean up
If Left(GetEmailArray, 2) = "; " Then
    GetEmailArray = Right(GetEmailArray, Len(GetEmailArray) - 2)
End If

'show us the money
MsgBox GetEmailArray

언급URL : https://stackoverflow.com/questions/7000334/deleting-elements-in-an-array-if-element-is-a-certain-value-vba

반응형