Làm thế nào thay đổi vùng chọn bằng VBA?

Liên hệ QC

phamduylong

-
Thành viên đã mất
Tham gia
30/12/06
Bài viết
918
Được thích
2,368
Nghề nghiệp
Giáo viên
Có vấn đề này thấy đơn giản mà tìm hoài không ra đáp số.
Có 2 vùng: A=Range("A1:G20"), B=Range("C3:D4")
Làm sao xác định được vùng C=A-C (là vùng A mà loại bỏ các ô trong vùng B) bằng VBA ?
 
Lần chỉnh sửa cuối:
phamduylong đã viết:
Có vấn đề này thấy đơn giản mà tìm hoài không ra đáp số.
Có 2 vùng: A=Range("A1:G20"), B=Range("C3:D4")
Làm sao xác định được vùng C=A-C (là vùng A mà loại bỏ các ô trong vùng B) bằng VBA ?
Chào Duy Long
Duy Long xem file ví dụ này xem. Mong rằng, hiểu đúng ý bạn.

Thân!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Có 2 vùng: A=Range("A1:G20"), B=Range("C3:D4")
Làm sao xác định được vùng C=A-B bằng VBA ?
Mình có cách củ chuối, như sau:
Mã:
  Option Explicit[b]
Sub Range11()[/b]
 Dim Rng As Range, RngA As Range, RngB As Range, RngC As Range
 Set RngA = Range("A1:E16")
 Set RngB = Range("B7:C10")
 For Each Rng In RngA
    If Intersect(Rng, RngB) Is Nothing Then
        If RngC Is Nothing Then
            Set RngC = Rng
        Else
            Set RngC = Union(RngC, Rng)
    End If:     End If
 Next Rng
 MsgBox RngC.Address[b]
End Sub[/b]
 
Upvote 0
Cách của Bác SA hay chứ.
Bác SA cho em xin "củ chuối" này về ngâm với. hi hi hi.

LVD
 
Upvote 0
Dễ hiểu thật. Bác SA ơi còn bao nhiêu "củ chuối" em xin hết nhé.
Cám ơn Bác SA nhiều !

TDN
 
Upvote 0
SA_DQ đã viết:
Mình có cách củ chuối
Mã:
Đúng là quá hay ! Cám ơn củ chuối của [COLOR=red][B]SA_DQ[/B][/COLOR] và [COLOR=red][B]tedaynui[/B][/COLOR].
Mình đang cần cái này để làm lại chương trình chuyển bảng mã cho bảng tính sử dụng nhiều bảng mã.
Từ code của SA_DQ, tôi viết lại thủ tục để chọn lại vùng A - vùng B: 
 
[code]
'==========
Sub RangeA_B(RngA As Range, RngB As Range)
'RangeA(RangeB)
Dim Rng As Range, RngN As Range, RngC As Range
For Each Rng In RngA
  If Intersect(Rng, RngB) Is Nothing Then
    If RngC Is Nothing Then
      Set RngC = Rng
    Else
      Set RngC = Union(RngC, Rng)
    End If
  End If
Next
If RngC Is Nothing Then
  MsgBox "Vung chon rong"
Else
  RngC.Select
End If
End Sub
'===========
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi xin giới thiệu cũng ý tưởng tương tự từ:
http://www.dailydoseofexcel.com/

Mã:
Function Union(Rng1 As Range, Rng2 As Range) As Range
    If Rng1 Is Nothing Then
        Set Union = Rng2
    ElseIf Rng2 Is Nothing Then
        Set Union = Rng1
    Else
        Set Union = Application.Union(Rng1, Rng2)
        End If
    End Function



Mã:
Function SubtractFirstPrinciples(Rng1 As Range, Rng2 As Range) As Range
    On Error Resume Next
    If Application.Intersect(Rng1, Rng2).Address <> Rng2.Address Then _
        Exit Function
    On Error GoTo 0
    Dim aCell As Range
    For Each aCell In Rng1
        Dim Rslt As Range
        If Application.Intersect(aCell, Rng2) Is Nothing Then
            Set Rslt = Union(Rslt, aCell)
            End If
        Next aCell
    Set SubtractFirstPrinciples = Rslt
    End Function

Sub testSubtractFirstPrinciples()
    Debug.Print SubtractFirstPrinciples( _
        Sheets(1).Range("A1:f10"), _
        Sheets(1).Range("A1,b2,c3,d4:e5,f6")).Address
End Sub

Lê Văn Duyệt
 
Upvote 0
Một trường hợp khác:
Một sheet có dữ liệu như hình dưới. Dữ liệu cần chọn là các ô chứa giá trị "ccc" ("ccc" là dữ liệu bât kỳ). Nhưng do hơi làm biếng, bấm chọn 1 lèo các ô như hình 1

Range1-1.jpg

Hình 1

Làm thế nào để VBA chọn lại vùng mới như hình 2 là 1 hình chữ nhật nhỏ nhất chứa tất cả các ô có giá trị trong vùng chọn 1 ?

Range2-1.jpg

Hình 2
 
Upvote 0
Một trường hợp khác:
Một sheet có dữ liệu như hình dưới. Dữ liệu cần chọn là các ô chứa giá trị "ccc" ("ccc" là dữ liệu bât kỳ). Nhưng do hơi làm biếng, bấm chọn 1 lèo các ô như hình 1

Làm thế nào để VBA chọn lại vùng mới như hình 2 là 1 hình chữ nhật nhỏ nhất chứa tất cả các ô có giá trị trong vùng chọn 1 ?

Anh thử code này xem :

PHP:
Sub AutoSelect()
    On Error Resume Next
    With Selection.SpecialCells(2)
        Intersect(.EntireRow, .EntireColumn).Select
    End With
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Thêm một tham khảo

PHP:
Option Explicit
Sub Seletor()
 Dim Clls As Range
 Dim rMax As Long, rMin As Long, cMax As Byte, cMin As Byte
 
 With Selection
   rMin = .Cells(1, 1).Row + .Rows.Count
   cMin = .Cells(1, 1).Column + .Columns.Count
 End With
 For Each Clls In Selection
   If Clls.Value = "GPE.COM" Then
      If rMin > Clls.Row Then rMin = Clls.Row
      If rMax < Clls.Row Then rMax = Clls.Row
      If cMin > Clls.Column Then cMin = Clls.Column
      If cMax < Clls.Column Then cMax = Clls.Column
   End If
 Next Clls
 MsgBox Range(Cells(rMin, cMin), Cells(rMax, cMax)).Address
End Sub
 
Upvote 0
Anh thử code này xem :

PHP:
Sub AutoSelect()
    On Error Resume Next
    With Selection.SpecialCells(2)
        Intersect(.EntireRow, .EntireColumn).Select
    End With
End Sub
Code này chưa đúng đâu nha! (Nhưng ý tưởng khá hay)
Code sẽ sai nếu vùng chọn có dòng rổng hoặc cột rổng (tức bị cách dòng hoặc cách cột)
---------------------
PHP:
Option Explicit
Sub Seletor()
 Dim Clls As Range
 Dim rMax As Long, rMin As Long, cMax As Byte, cMin As Byte
 
 With Selection
   rMin = .Cells(1, 1).Row + .Rows.Count
   cMin = .Cells(1, 1).Column + .Columns.Count
 End With
 For Each Clls In Selection
   If Clls.Value = "GPE.COM" Then
      If rMin > Clls.Row Then rMin = Clls.Row
      If rMax < Clls.Row Then rMax = Clls.Row
      If cMin > Clls.Column Then cMin = Clls.Column
      If cMax < Clls.Column Then cMax = Clls.Column
   End If
 Next Clls
 MsgBox Range(Cells(rMin, cMin), Cells(rMax, cMax)).Address
End Sub
Không hiểu sau em chạy code của sư phụ cứ bị lổi hoài mà không tìm được nguyên nhân
-----------------
Em thì làm như sau:
PHP:
Sub Selector()
  Dim i As Long, Rng As Range
  On Error Resume Next
  If Selection.Count = 1 Then
    Selection.Select
  Else
    With Selection.SpecialCells(2)
      Set Rng = .Areas(1)
      For i = 1 To .Areas.Count
        Set Rng = Range(Rng, .Areas(i))
      Next i
    End With
    Rng.Select
  End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Tìm ra chưa zậy? Thêm 1 cái nữa xem tìm luôn thể; hì, hì, . . .

Không hiểu sau em chạy code cứ bị lổi hoài mà không tìm được nguyên nhân
Có lần mình bị lỗi do quên chọn vùng dữ liệu trước khi chạy nó


PHP:
Option Explicit
Sub Seletor()
 Dim Clls As Range, Rng As Range, sRng As Range
 Dim MyAdd As String
 Dim rMax As Long, rMin As Long, cMax As Byte, cMin As Byte
 
 Set Rng = Selection
 With Rng
   rMin = .Cells(1, 1).Row + .Rows.Count
   cMin = .Cells(1, 1).Column + .Columns.Count
 End With
 
 Set sRng = Rng.Find("GPE.COM", , xlFormulas, xlWhole)
 If Not sRng Is Nothing Then
   MyAdd = sRng.Address
   Do
      With sRng
         If rMin > .Row Then rMin = .Row
         If rMax < .Row Then rMax = .Row
         If cMin > .Column Then cMin = .Column
         If cMax < .Column Then cMax = .Column
      End With
      Set sRng = Rng.FindNext(sRng)
   Loop While Not sRng Is Nothing And sRng.Address <> MyAdd
 End If
 Range(Cells(rMin, cMin), Cells(rMax, cMax)).Select
End Sub
 
Upvote 0
PHP:
Option Explicit
Sub Seletor()
 Dim Clls As Range, Rng As Range, sRng As Range
 Dim MyAdd As String
 Dim rMax As Long, rMin As Long, cMax As Byte, cMin As Byte
 
 Set Rng = Selection
 With Rng
   rMin = .Cells(1, 1).Row + .Rows.Count
   cMin = .Cells(1, 1).Column + .Columns.Count
 End With
 
 Set sRng = Rng.Find("GPE.COM", , xlFormulas, xlWhole)
 If Not sRng Is Nothing Then
   MyAdd = sRng.Address
   Do
      With sRng
         If rMin > .Row Then rMin = .Row
         If rMax < .Row Then rMax = .Row
         If cMin > .Column Then cMin = .Column
         If cMax < .Column Then cMax = .Column
      End With
      Set sRng = Rng.FindNext(sRng)
   Loop While Not sRng Is Nothing And sRng.Address <> MyAdd
 End If
 Range(Cells(rMin, cMin), Cells(rMax, cMax)).Select
End Sub
Vậy phải sửa code của sư phụ lại thành vầy chăng:
PHP:
Sub Seletor()
 Dim Clls As Range, Rng As Range, sRng As Range
 Dim MyAdd As String
 Dim rMax As Long, rMin As Long, cMax As Byte, cMin As Byte
 
 Set Rng = Selection
 With Rng
   rMin = .Cells(1, 1).Row + .Rows.Count
   cMin = .Cells(1, 1).Column + .Columns.Count
 End With
 
 Set sRng = Rng.Find("*", , xlFormulas, xlWhole)
 If Not sRng Is Nothing Then
   MyAdd = sRng.Address
   Do
      With sRng
         If rMin > .Row Then rMin = .Row
         If rMax < .Row Then rMax = .Row
         If cMin > .Column Then cMin = .Column
         If cMax < .Column Then cMax = .Column
      End With
      Set sRng = Rng.FindNext(sRng)
   Loop While Not sRng Is Nothing And sRng.Address <> MyAdd
 End If
 Range(Cells(rMin, cMin), Cells(rMax, cMax)).Select
End Sub
 
Upvote 0
ptlong04x1, SA_DQ : bị lỗi như nhận xét của ndu96081631
ndu96081631 : đúng khi vùng chọn không phải là công thức, nó loại ô công thức ra khỏi vùng chọn (ô E11 là công thức).

ndu96081631.jpg


Các bạn có nhiều ý tưởng hay quá. Tiếp thu hết !
 
Upvote 0
Vậy phải sửa code của sư phụ lại thành vầy chăng:

Không được sửa à nha, một khi chưa có í kiến của tác giả topic!

Hãy xem lại hình mà tác giả đưa ra, đó là tìm vủng "Nhỏ nhứt" có chưa chuỗi 'cccc'

Thay như chú, thì có khi chưa đạt ý đồ của tác giả đâu ha!
 
Upvote 0
Có cách nào không dùng vòng lặp không nhỉ?
 
Upvote 0
ptlong04x1, SA_DQ : bị lỗi như nhận xét của ndu96081631
ndu96081631 : đúng khi vùng chọn không phải là công thức, nó loại ô công thức ra khỏi vùng chọn (ô E11 là công thức).
!
Thì thầy thêm cái Selection.Special(3) vào nữa
Chẳng hạn là vầy:
PHP:
Sub Selector()
  Dim i As Long, Rng As Range, ValRng As Range, ForRng As Range
  On Error Resume Next
  If Selection.Count = 1 Then
    Selection.Select
  Else
    Set ValRng = Selection.SpecialCells(2)
    Set ForRng = Selection.SpecialCells(3)
    If ForRng Is Nothing Then Set ForRng = ValRng
    If ValRng Is Nothing Then Set ValRng = ForRng
    With Union(ValRng, ForRng)
      Set Rng = .Areas(1)
      For i = 1 To .Areas.Count
        Set Rng = Range(Rng, .Areas(i))
      Next i
    End With
    Rng.Select
  End If
End Sub
Thầy test lại giùm em với
 
Lần chỉnh sửa cuối:
Upvote 0
Không được sửa à nha, một khi chưa có í kiến của tác giả topic!

Hãy xem lại hình mà tác giả đưa ra, đó là tìm vủng "Nhỏ nhứt" có chưa chuỗi 'cccc'

Thay như chú, thì có khi chưa đạt ý đồ của tác giả đâu ha!
Dạ! Em hiểu ý của anh... nhưng vì em đọc câu hỏi của thầy Long, thấy có đoạn:
Một trường hợp khác:
Một sheet có dữ liệu như hình dưới. Dữ liệu cần chọn là các ô chứa giá trị "ccc" ("ccc" là dữ liệu bât kỳ). Nhưng do hơi làm biếng, bấm chọn 1 lèo các ô như hình 1
Chổ màu đỏ ấy sư phụ
 
Upvote 0
Thì thầy thêm cái Selection.Special(3) vào nữa
Test đã đúng ý đồ. Cám ơn tất cả các bạn.
Mình vận dụng cái này vào việc loại các ô không có dữ liệu ra khỏi vùng chọn. Ví dụ như chuyển mã.
Người dùng bấm chọn toàn bộ bảng tính. Chuyển mã phải chuyển từng ô. Chạy vòng lặp chuyển hết các ô chọn thì ... !
 
Upvote 0
Test đã đúng ý đồ. Cám ơn tất cả các bạn.
Mình vận dụng cái này vào việc loại các ô không có dữ liệu ra khỏi vùng chọn. Ví dụ như chuyển mã.
Người dùng bấm chọn toàn bộ bảng tính. Chuyển mã phải chuyển từng ô. Chạy vòng lặp chuyển hết các ô chọn thì ... !
Nếu vậy thì vùng chọn này vẫn.. thừa thầy à (nếu trong vùng có cell rổng)
Sao thầy không dùng 2 vòng lập: 1 duyệt qua Selection.SpecialCells(2) và 1 duyệt qua Selection.SpecialCells(3) ---> Như vậy ăn chắc vừa đủ, không thừa, không thiếu
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom