VBA: 사용자가 셀을 삭제하면 Range 객체는 어떻게 됩니까?
vba에 변수를 가진 모듈이 있다고 가정합니다.r
타입의Range
어느 시점에서 Range 객체(액티브 셀 등)를 저장한다고 가정합니다.자, 이제 질문하겠습니다.가치에는 어떤 변화가 있을까?r
사용자가 셀(셀 값뿐만 아니라 셀)을 삭제했을 경우
나는 VBA에서 이것을 알아내려고 노력했지만 성공하지 못했다.결과는 이상하다. r
아니다Nothing
, 의 가치r
유형으로 보고되다Range
그러나 디버거 창에서 해당 속성을 확인하려고 하면 각 속성 값이 "개체 필요"로 보고됩니다.
프로그래밍 방식으로 변수인지 아닌지를 결정하려면 어떻게 해야 합니까?r
이 상태인가요, 아닌가요?
에러를 생성하여 검출하지 않고 실행할 수 있습니까?
좋은 질문입니다!지금까지 이것에 대해 생각해 본 적은 없지만, 이 함수는 초기화된 범위(아무것도 아님)를 식별하지만 셀이 삭제되었기 때문에 현재 "개체 필요" 상태에 있는 범위를 식별합니다.
Function RangeWasDeclaredAndEntirelyDeleted(r As Range) As Boolean
Dim TestAddress As String
If r Is Nothing Then
Exit Function
End If
On Error Resume Next
TestAddress = r.Address
If Err.Number = 424 Then 'object required
RangeWasDeclaredAndEntirelyDeleted = True
End If
End Function
다음과 같이 테스트할 수 있습니다.
Sub test()
Dim r As Range
Debug.Print RangeWasDeclaredAndEntirelyDeleted(r)
Set r = ActiveSheet.Range("A1")
Debug.Print RangeWasDeclaredAndEntirelyDeleted(r)
r.EntireRow.Delete
Debug.Print RangeWasDeclaredAndEntirelyDeleted(r)
End Sub
VBA에서 Set 키워드를 사용하면 지정한 워크시트에 있는 워크시트의 Range 객체에 대한 포인터가 백그라운드에서 생성된다고 생각합니다(각 셀은 지정된 범위에 대한 워크시트의 셀 컬렉션에 있는 개체입니다).메모리 내에서 범위를 참조하고 있을 때 범위가 삭제되면 범위 변수가 가리킨 개체의 메모리가 할당 해제됩니다.
그러나 Range 변수에는 최근에 삭제한 Range 객체에 대한 포인터가 포함되어 있을 가능성이 매우 높기 때문에 아무것도 아니지만 이 객체가 가리키는 포인터는 더 이상 존재하지 않기 때문에 변수를 다시 사용하려고 하면 문제가 발생합니다.
이 코드를 체크하면 무슨 뜻인지 알 수 있습니다.
Public Sub test2()
Dim r As Excel.Range
Debug.Print ObjPtr(r) ' 0
Set r = ActiveSheet.Range("A1")
Debug.Print ObjPtr(r) ' some address
r.Value = "Hello"
r.Delete
Debug.Print ObjPtr(r) ' same address as before
End Sub
ObjPtr()에 대한 자세한 내용은 다음 문서를 참조하십시오.http://support.microsoft.com/kb/199824
따라서 객체에 대한 유효한 주소가 있는 동안 객체가 삭제되었기 때문에 객체는 더 이상 존재하지 않습니다.게다가 「Is Nothing」은, 포인터의 주소를 체크하는 것 뿐입니다(VBA는 변수를 「Set」라고 믿고 있는 것 같습니다).
이 문제를 어떻게 해결할 수 있을지 아쉽지만, 현재로선 깔끔한 방법을 찾을 수 없습니다(이 문제를 해결할 수 있는 좋은 방법을 찾는 사람이 있으면 게시해 주세요!).다음과 같이 On Error Resume Next를 사용할 수 있습니다.
Public Sub test3()
Dim r As Excel.Range
Debug.Print ObjPtr(r) ' 0
Set r = ActiveSheet.Range("A1")
Debug.Print ObjPtr(r) ' some address
r.Value = "Hello"
r.Delete
Debug.Print ObjPtr(r) ' same address as before
On Error Resume Next
Debug.Print r.Value
If (Err.Number <> 0) Then
Debug.Print "We have a problem here..."; Err.Number; Err.Description
End If
On Error GoTo 0
End Sub
변수 r이 이 상태인지 아닌지는 프로그래밍 방식으로 어떻게 판단할 수 있습니까?
에러를 생성하여 검출하지 않고 실행할 수 있습니까?
아니요.
제가 아는 한, 이 상태를 확실하게 테스트할 수 없습니다. 오류를 발생시키고 발견하지 않으면 안 됩니다.
귀하의 질문은 다른 곳에서 확인 및 논의되었습니다.Excel/VBA 블로그의 거물 2명(Dick Kusleika와 Rob Bobey)이 조사했는데, 그 안에서 유익한 정보를 찾을 수 있을지도 모릅니다.하지만 대답은 '아니오'입니다.
대체로, 꽤 걱정스러운 답변이 있는 좋은 질문입니다.
범위 개체가 현재 유효하지 않은지 테스트하려면 다음 기능을 사용합니다.
Public Function InvalidRangeReference(r As Range) As Boolean
On Error Resume Next
If r.Count = 0 Then
InvalidRangeReference = Err
End If
End Function
언급URL : https://stackoverflow.com/questions/12127311/vba-what-happens-to-range-objects-if-user-deletes-cells
'programing' 카테고리의 다른 글
NTFS 접속점과 심볼릭 링크의 차이점은 무엇입니까? (0) | 2023.04.22 |
---|---|
Xcode 아래 x86_64 아키텍처에 대한 중복 기호 (0) | 2023.04.22 |
MVVM이 EventArgs를 명령 매개 변수로 전달 (0) | 2023.04.22 |
UITableView에서 빈 셀을 삭제하는 방법 (0) | 2023.04.22 |
Git serve : 그렇게 심플하게 하고 싶다 (0) | 2023.04.22 |