Lấy giá trị tuần tự liên tục trong 1 cột!

Liên hệ QC

alias1313

Thành viên hoạt động
Tham gia
7/4/17
Bài viết
163
Được thích
13
Em cần lấy giá trị trong một cột ( >1000 hàng) bằng cách sử dụng VBA, mong các anh giúp đỡ!

Qui luật để lấy như sau:
Tai cột E
- Giá trị đầu tiên > 50 lấy, gán giá trị ra ô excel cột G
- Giá trị tiếp theo < 50 lấy, gán giá trị ra ô excel tiếp theo ô trên
- Giá trị tiếp theo > 50 lấy
- Giá trị tiếp theo < 50 lấy.

Cứ lấy xen kẽ như vậy! Giá trị lấy được gán ra cột G.
Em viết 1 đoạn code như bên dưới, nhưng em không biết muốn lấy giá trị tiếp theo phải viết thế nào để hàm for nó hiểu.
Mong các anh giúp em! Em cảm ơn!

Mã:
Sub LocGiaTri()

   Dim range1 as range

For each range1 in Range("E1:E20")

If range1.value > 50 then

End if

Next range1

End sub
 

File đính kèm

  • LayGiaTri.xlsx
    8.8 KB · Đọc: 16
Em cần lấy giá trị trong một cột ( >1000 hàng) bằng cách sử dụng VBA, mong các anh giúp đỡ!

Qui luật để lấy như sau:
Tai cột E
- Giá trị đầu tiên > 50 lấy, gán giá trị ra ô excel cột G
- Giá trị tiếp theo < 50 lấy, gán giá trị ra ô excel tiếp theo ô trên
- Giá trị tiếp theo > 50 lấy
- Giá trị tiếp theo < 50 lấy.

Cứ lấy xen kẽ như vậy! Giá trị lấy được gán ra cột G.
Em viết 1 đoạn code như bên dưới, nhưng em không biết muốn lấy giá trị tiếp theo phải viết thế nào để hàm for nó hiểu.
Mong các anh giúp em! Em cảm ơn!

Mã:
Sub LocGiaTri()

   Dim range1 as range

For each range1 in Range("E1:E20")

If range1.value > 50 then

End if

Next range1

End sub
Số đúng = 50 cũng không lấy hả bạn?
 
Upvote 0
Em cần lấy giá trị trong một cột ( >1000 hàng) bằng cách sử dụng VBA, mong các anh giúp đỡ!

Qui luật để lấy như sau:
Tai cột E
- Giá trị đầu tiên > 50 lấy, gán giá trị ra ô excel cột G
- Giá trị tiếp theo < 50 lấy, gán giá trị ra ô excel tiếp theo ô trên
- Giá trị tiếp theo > 50 lấy
- Giá trị tiếp theo < 50 lấy.

Cứ lấy xen kẽ như vậy! Giá trị lấy được gán ra cột G.
Em viết 1 đoạn code như bên dưới, nhưng em không biết muốn lấy giá trị tiếp theo phải viết thế nào để hàm for nó hiểu.
Mong các anh giúp em! Em cảm ơn!

Mã:
Sub LocGiaTri()

   Dim range1 as range

For each range1 in Range("E1:E20")

If range1.value > 50 then

End if

Next range1

End sub
Bạn kiểm tra xem đúng không
Mã:
Sub aa()
    Dim i, lonhon
    Cells(4, 7) = Cells(4, 5)
    If Cells(4, 5) > 50 Then lonhon = True
    For i = 5 To 17
        If Cells(i, 5) > 50 Then
            If lonhon = False Then
                lonhon = True
                Cells(i, 7) = Cells(i, 5)
            End If
        Else
            If lonhon Then
                lonhon = False
                Cells(i, 7) = Cells(i, 5)
            End If
        End If
    Next
End Sub
 
Upvote 0
Mã:
sub vidu()
Const N as long =50
Dim a(), b(), s,i as long, j as long, flag as boolean
a= sheet1.range("e1:e20").value
Redim b(1 to ubound(a,1),1 to 1)
flag=true
For i=1 to ubound(a,1) step 1
s=a(i,1)
If isnumeric(s)=true then
If (s>=N)=flag then
flag=not flag
j=j+1
b(j,1)=s
End if
End if
Next i
Sheet1.range("g1").resize(j,1)=b
End sub
. Viết chay trên điện thoại nên hơi xấu chút. :)
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
sub vidu()
Const N as long =50
Dim a(), b(), s,i as long, j as long, flag as boolean
a= sheet1.range("e1:e20").value
Redim b(1 to ubound(a,1),1 to 1)
flag=true
For i=1 to ubond(a,1) step 1
s=a(i,1)
If isnumeric(s)=true then
If (s>=N)=flag then
flag=not flag
j=j+1
b(j,1)=s
End if
End if
Next i
Sheet1.range("g1").resize(j,1)=b
End sub
. Viết chay trên điện thoại nên hơi xấu chút. :)
Trường hợp bài này bạn không cần phải flag lớn hay nhỏ. Chỉ cần xét xem hiện tại số kết quả là chẵn hay lẻ.
 
Upvote 0
Mã:
sub vidu()
Const N as long =50
Dim a(), b(), s,i as long, j as long, flag as boolean
a= sheet1.range("e1:e20").value
Redim b(1 to ubound(a,1),1 to 1)
flag=true
For i=1 to ubound(a,1) step 1
s=a(i,1)
If isnumeric(s)=true then
If (s>=N)=flag then
flag=not flag
j=j+1
b(j,1)=s
End if
End if
Next i
Sheet1.range("g1").resize(j,1)=b
End sub
. Viết chay trên điện thoại nên hơi xấu chút. :)
Thiếu 1 chữ "u" đúng không Befaint?
 
Upvote 0
Dạ em quên: lấy >= 50.

Mong Thầy giúp em! Em cảm ơn Thầy!
Viết vầy:
Mã:
Sub Test()
  Dim arr
  Dim idx As Long
  Dim bChk As Boolean
  arr = Sheet1.Range("E4:E1000").Value
  ReDim aRes(1 To UBound(arr), 1 To 1)
  For idx = 1 To UBound(arr)
    If arr(idx, 1) <> Empty Then
      If bChk = (arr(idx, 1) < 50) Then
        aRes(idx, 1) = arr(idx, 1)
        bChk = Not bChk
      End If
    End If
  Next
  Sheet1.Range("G4:G1000").Value = aRes
End Sub
 
Upvote 0
Bạn kiểm tra xem đúng không
Mã:
Sub aa()
    Dim i, lonhon
    Cells(4, 7) = Cells(4, 5)
    If Cells(4, 5) > 50 Then lonhon = True
    For i = 5 To 17
        If Cells(i, 5) > 50 Then
            If lonhon = False Then
                lonhon = True
                Cells(i, 7) = Cells(i, 5)
            End If
        Else
            If lonhon Then
                lonhon = False
                Cells(i, 7) = Cells(i, 5)
            End If
        End If
    Next
End Sub

Code anh giúp chạy hoàn hảo! Nhưng anh có thể giải thích giùm em các dòng code đc ko anh!
Em chưa gặp kiểu "lonhon = true" bao giờ nên xem mãi không hiểu cách code vận hành!
Mong anh giúp đỡ!
 
Upvote 0
Code anh giúp chạy hoàn hảo! Nhưng anh có thể giải thích giùm em các dòng code đc ko anh!
Em chưa gặp kiểu "lonhon = true" bao giờ nên xem mãi không hiểu cách code vận hành!
Mong anh giúp đỡ!
MÌnh hơi khó giải thích, tạm như thế này
số 5, 7 tức là cột E, G
for i = 5 to 17 tức là từ dòng 5 đến dòng 17
cells(i,5) tức là dòng i cột E ( i ở đâu nằm trong khoảng 5 - 17)
lonhon thì là lớn hơn, do xét liên tục nên mình dùng biến này để kiểm tra, nếu giá trị hiện tại lớn hơn 50 thì kiểm tra xem biến lonhon, nếu lớn hơn rồi thì không xét nữa nếu số trc điền là nhỏ hơn (lonhon = false) thì lấy giá trị. Xét cho trường hợp ngược lại
 
Upvote 0
Upvote 0
Viết vầy:
Mã:
Sub Test()
  Dim arr
  Dim idx As Long
  Dim bChk As Boolean
  arr = Sheet1.Range("E4:E1000").Value
  ReDim aRes(1 To UBound(arr), 1 To 1)
  For idx = 1 To UBound(arr)
    If arr(idx, 1) <> Empty Then
      If bChk = (arr(idx, 1) < 50) Then
        aRes(idx, 1) = arr(idx, 1)
        bChk = Not bChk
      End If
    End If
  Next
  Sheet1.Range("G4:G1000").Value = aRes
End Sub

Code chạy chính xác rồi thưa Thầy!
Thầy giúp em giải thích đoạn code dưới nha Thầy @ndu96081631 ! Em không hiểu đoạn đó!
Em thấy: (arr(idx, 1) = 34 thì bChk = (arr(idx, 1) < 50) = true, Nhưng nó lại ra False.
và : "bChk = Not bChk" để làm gì em cũng ko biết!
Mong Thầy giúp em!

Mã:
If bChk = (arr(idx, 1) < 50) Then

        aRes(idx, 1) = arr(idx, 1)

        bChk = Not bChk

      End If

Em cảm ơn Thầy rất nhiều!
Bài đã được tự động gộp:

Có thấy đúng đâu trời
???!!!
----------------------

lonhon chắc là lộn hòn. Mà lonhon = True có nghĩa là chắc chắn bị lộn hòn

Dạ! code bị nhầm nếu giá trị đầu tiên < 50, sẽ chạy ngược! hihi!
 
Upvote 0
Code chạy chính xác rồi thưa Thầy!
Thầy giúp em giải thích đoạn code dưới nha Thầy @ndu96081631 ! Em không hiểu đoạn đó!
Em thấy: (arr(idx, 1) = 34 thì bChk = (arr(idx, 1) < 50) = true, Nhưng nó lại ra False.
và : "bChk = Not bChk" để làm gì em cũng ko biết!
Mong Thầy giúp em!

Mã:
If bChk = (arr(idx, 1) < 50) Then

        aRes(idx, 1) = arr(idx, 1)

        bChk = Not bChk

      End If

Em cảm ơn Thầy rất nhiều!
- Đầu tiên bChk chưa có giá trị nên nó =False
- Vào vòng lập ta xét biểu thức (arr(idx, 1) < 50) sẽ cho kết quả =True (vì hiện arr(idx, 1) đang = 32) trong khi bChk đang =False. So sánh False =True sẽ ra kết quả sai (tức False) nên không thỏa điều kiện
- Chạy tiếp đến khi gặp giá trị 52 thì biểu thức (arr(idx, 1) < 50) sẽ cho kết quả =False trong khi bChk vẫn đang =False. So sánh False =False sẽ ra kết quả đúng (tức True) ---> Thỏa điều kiện ta lấy giá trị vào mảng đồng thời làm động tác bChk = Not bChk để "lật" giá trị bChk từ True thành False (hoặc từ False thành True)
- Cứ thế tiếp tục
vậy thôi
------------------------
. Có đúng đâu???
"gán giá trị ra ô excel tiếp theo ô trên"
Đang dùng điện thoại có xem được file không đấy? Lấy giá trị và gán ngang hàng với cell tương ứng, không phải lấy xong rồi dồn 1 cục đâu
 
Upvote 0
- Đầu tiên bChk chưa có giá trị nên nó =False
- Vào vòng lập ta xét biểu thức (arr(idx, 1) < 50) sẽ cho kết quả =True (vì hiện arr(idx, 1) đang = 32) trong khi bChk đang =False. So sánh False =True sẽ ra kết quả sai (tức False) nên không thỏa điều kiện
- Chạy tiếp đến khi gặp giá trị 52 thì biểu thức (arr(idx, 1) < 50) sẽ cho kết quả =False trong khi bChk vẫn đang =False. So sánh False =False sẽ ra kết quả đúng (tức True) ---> Thỏa điều kiện ta lấy giá trị vào mảng đồng thời làm động tác bChk = Not bChk để "lật" giá trị bChk từ True thành False (hoặc từ False thành True)
- Cứ thế tiếp tục
vậy thôi
------------------------

Đang dùng điện thoại có xem được file không đấy? Lấy giá trị và gán ngang hàng với cell tương ứng, không phải lấy xong rồi dồn 1 cục đâu


haha!...Em hiểu rồi...Cảm ơn Thầy @ndu96081631 rất nhiều ạ!
@befaint : Code chạy chính xác rồi Bác ơi! thử đổi giá trị các kiểu đều chạy tốt hêt! hihi!
 
Upvote 0
. Có đúng đâu???
"gán giá trị ra ô excel tiếp theo ô trên"

Giờ em mới thấy Code của anh! em đã test! và code chạy đúng theo kiểu: " gán giá trị ra ô excel tiếp theo ô trên"!
Cảm ơn anh rất nhiều!
Bài đã được tự động gộp:

Em cảm ơn Thầy @ndu96081631 cùng các anh rất nhiều!
Đã giúp em rất nhiều cách giải quyết vấn đề! Mặc dù chỉ vừa Post bài!
Mong Thầy và các anh luôn khỏe! hiihi!

Trân trọng!
Bài đã được tự động gộp:

MÌnh hơi khó giải thích, tạm như thế này
số 5, 7 tức là cột E, G
for i = 5 to 17 tức là từ dòng 5 đến dòng 17
cells(i,5) tức là dòng i cột E ( i ở đâu nằm trong khoảng 5 - 17)
lonhon thì là lớn hơn, do xét liên tục nên mình dùng biến này để kiểm tra, nếu giá trị hiện tại lớn hơn 50 thì kiểm tra xem biến lonhon, nếu lớn hơn rồi thì không xét nữa nếu số trc điền là nhỏ hơn (lonhon = false) thì lấy giá trị. Xét cho trường hợp ngược lại

Em cảm ơn anh nhiều!
 
Lần chỉnh sửa cuối:
Upvote 0
Mã:
Sub Test()
  Dim arr
  Dim idx As Long
  Dim bChk As Boolean
  arr = Sheet1.Range("E4:E1000").Value
  ReDim aRes(1 To UBound(arr), 1 To 1)
  For idx = 1 To UBound(arr)
    If arr(idx, 1) <> Empty Then
      If bChk = (arr(idx, 1) < 50) Then
        aRes(idx, 1) = arr(idx, 1)
        bChk = Not bChk
      End If
    End If
  Next
  Sheet1.Range("G4:G1000").Value = aRes
End Sub

Code trên khi chạy trên 1 sheet thì không sao, nhưng khi chạy trên nhiều sheet 1 lúc, thì bị tình trạng:
- Giá trị: bChk - cuối cùng của sheet1 tính sang cho sheet2 ( khi sang sheet2 phải reset lại biến bChr) => giá trị đầu tiên lấy bị sai ( lúc >50, lúc < 50)
- Em mò mãi mới thấy cách sửa đc lỗi này bằng cách thêm bChk = false để reset. và thấy khi chạy nhiều sheet kết quả vẫn đúng.
-Em muốn hỏi: đó có phải là cách reset biến Bolean không và cách đúng nhất là gì ạ!
Em cảm ơn Thầy cùng các anh!

Mã:
Dim arr

  Dim idx As Long

  Dim bChk As Boolean

  arr = Sheet1.Range("E4:E1000").Value

  ReDim aRes(1 To UBound(arr), 1 To 1)

  For idx = 1 To UBound(arr)

    If arr(idx, 1) <> Empty Then

      If bChk = (arr(idx, 1) < 50) Then

        aRes(idx, 1) = arr(idx, 1)

        bChk = Not bChk

      End If

    End If

  Next

  Sheet1.Range("G4:G1000").Value = aRes
  bChk = False
  End sub
 
Upvote 0
Gom 11 sheets rồi mới chạy code bài này. Tức là tối qua phải đăng bài gom 11 sheets trước, sáng nay đăng bài này.
Hoặc đăng một bài nêu hai yêu cầu luôn và ngồi chờ món súp cá thôi. :)
 
Upvote 0
Web KT
Back
Top Bottom