Những câu hỏi về code, xin giải thích các code, đề nghị các bạn gửi vào đây

Liên hệ QC
Status
Không mở trả lời sau này.

ST-Lu!

Love Wingchun
Tham gia
19/8/08
Bài viết
730
Được thích
546
Nghề nghiệp
Xích lô một thời
Kể từ hôm nay, tất cả những câu hỏi nhờ giải thích dùm một đoạn code, hay là hỏi những vấn đề linh tinh gì liên quan đến cách viết code, đề nghị các bạn gửi chung vào đây.

Những đề tài mới với tiêu đề: "Nhờ giải thích dùm đoạn code", mà không nói rõ là code gì, code dùng để làm gì, sẽ bị xóa.

BQT

----------------------------------------------------------------------------------------------------------------


Em xin được hỏi 2 đoạn code sau có tương đương nhau ?

Cells(Cells.Rows.Count, 1).End(xlUp).Row có tương đương với [A65000].End(xlup).row

Cám ơn các anh chỉ giáo
 
Chỉnh sửa lần cuối bởi điều hành viên:
Nhờ làm bài toán sau bằng VBA (theo phương pháp mảng điền thẳng Value) vào ô kết quả

Tìm các bài toán trên diễn đàn để thực hành, tôi làm lại bài toán sau (điền kết quả vào cột I)
Tinhtong.jpg


Code viết chạy kết quả chính xác, nhưng có cảm giác Code chưa được gọn lắm, xin nhờ tư vấn giúp tôi xem có thể rút gọn được không?

PHP:
Sub TinhTong()
    Dim i As Long, Dongcuoi As Long, Congviec As Long, n As Long
    Dim kk As Long, VLK As Long, Arr(), Tmp()
    Dongcuoi = Sheet1.Range("D65000").End(xlUp).Row
    ReDim Tmp(1 To 1)
    Congviec = Dongcuoi
    Range("I4:I1000").ClearContents
    For i = Dongcuoi To 4 Step -1
        If Cells(i, 4) = "TTPK" Then
            kk = i
            Congviec = i - 1
            m = m + 1
            ReDim Preserve Arr(1 To m)
            Arr(m) = Cells(i, 9).Address(0, 0)
        ElseIf Cells(i, 4) = "VL" Or Cells(i, 4) = "NC" Or Cells(i, 4) = "MTC" Then
            Cells(i, 9).Value = "=SUM(R[1]C:R[" & Congviec - i & "]C)*RC[-2]"
            Congviec = i - 1
            n = n + 1
            ReDim Preserve Tmp(1 To n)
            Tmp(n) = Cells(i, 9).Address(0, 0)
            m = m + 1
            ReDim Preserve Arr(1 To m)
            Arr(m) = Cells(i, 9).Address(0, 0)
        ElseIf Cells(i, 4) = "Vlkhac" Then
            VLK = i
        ElseIf Cells(i, 1) <> "" Then
            Cells(VLK, 9).Value = "=SUM(R[-1]C:R[" & i + 2 - VLK & "]C)*RC[-2]%"
            Cells(kk, 9).Value = "=" & "(" & Join(Tmp, "+") & ")" & "*1.5%"
            Cells(i, 9).Value = "=" & Join(Arr, "+")
            Congviec = i - 1
            n = 0
            m = 0
            VLK = 0
        Else
            Cells(i, 9).Formula = "=" & Cells(i, 7).Address(0, 0) & "*" & Cells(i, 8).Address(0, 0)
        End If
    Next
End Sub

Bài toán này tôi định làm thêm 1 phương pháp bằng VBA theo dạng mảng điền thẳng kết quả (value vào những ô cần điền) nhưng nghĩ mãi mà làm không ra, nhờ mọi ngưòi giúp cho tôi thêm cách này để tôi có điều kiện học hỏi.

Xin trân trọng cảm ơn.
 

File đính kèm

  • Bai toan goc.xls
    36 KB · Đọc: 15
Upvote 0
Cho em hỏi về Code lọc dữ liệu với ah:

PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim CrRng As Range
  If Not Intersect(Range("C1:C2"), Target) Is Nothing Then
    Range("A4:G1000").Clear
    Set CrRng = Range("C1:C2")
    With Sheets("Data")
      With .Range(.[A1], .[A65536].End(xlUp)).Resize(, 7)
        .AdvancedFilter 2, CrRng, Range("A4")
      End With
    End With
    Range([A4], [A65536].End(xlUp)).Resize(, 2).Offset(, 3).Delete 1
  End If
End Sub

xin kính mong được giúp đỡ
------------
Dấu <> ở ô C2 sheets(Detail) có phải là dạng toán tử không (tại sao không là ký tự khác?) hay nó thể hiện là chỉ lọc những ô không phải là ô rỗng tại cột TK Nợ, TK Có (tức cột D, E) ?
Trong Delete 1 thì 1 là gì ah?
 

File đính kèm

  • LocTK_1.xls
    45 KB · Đọc: 20
Lần chỉnh sửa cuối:
Upvote 0
Bác cứ ghi Macro chức năng của Advanced Filter là có đầy đủ mà (quan trọng là mình phải thực hành "cày" thật nhiều + Google thì mới nhanh ra được).
Về Delete 1 thì em tìm hiểu mãi chưa chưa biết nó là gì, nhưng em thử thấy bỏ đi nó vẫn vậy.
 
Upvote 0
Cho em hỏi về Code lọc dữ liệu với ah:

PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim CrRng As Range
  If Not Intersect(Range("C1:C2"), Target) Is Nothing Then
    Range("A4:G1000").Clear
    Set CrRng = Range("C1:C2")
    With Sheets("Data")
      With .Range(.[A1], .[A65536].End(xlUp)).Resize(, 7)
        .AdvancedFilter 2, CrRng, Range("A4")
      End With
    End With
    Range([A4], [A65536].End(xlUp)).Resize(, 2).Offset(, 3).Delete 1
  End If
End Sub

xin kính mong được giúp đỡ
------------
Dấu <> ở ô C2 sheets(Detail) có phải là dạng toán tử không (tại sao không là ký tự khác?) hay nó thể hiện là chỉ lọc những ô không phải là ô rỗng tại cột TK Nợ, TK Có (tức cột D, E) ?
Dấu <> này là 1 trong những điều kiện lọc của Advanced Filter, ý muốn nói khác rổng
Thật ra các hàm SUMIF, COUNTIF cũng dùng kiểu điều kiện này. Ví dụ =SUMIF(Data!D2:D9,"<>",Data!G2:G9) cho kết quả =15 ---> Tính tổng vùng Data!G2:G9 với điều kiện vùng Data!D2:D9 <> rổng
Ngoài điều kiện "<>" còn có điều kiện "=" (ý nghĩa ngược lại)
----------------------------------
Trong Delete 1 thì 1 là gì ah?
Do lọc sheet Data nhưng lại muốn bỏ bớt 2 cột TK Nợ và TK Có nên phải xóa bớt ấy mà
Thật ra do ngày xưa NGU nên mới viết vậy! Nếu bây giờ thì tôi sẽ viết vầy
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim CrRng As Range
  If Not Intersect(Range("C1:C2"), Target) Is Nothing Then
    Range("[COLOR=#ff0000][B]A5:G1000[/B][/COLOR]").Clear
    Set CrRng = Range("C1:C2")
    With Sheets("Data")
      With .Range(.[A1], .[A65536].End(xlUp)).Resize(, 7)
        .AdvancedFilter 2, CrRng, Range("[COLOR=#ff0000][B]A4:E4[/B][/COLOR]")
      End With
    End With
  End If
End Sub
Khỏi Delete 1 gì cả vẫn cho kết quả đúng ý
 
Lần chỉnh sửa cuối:
Upvote 0
(1) Về Delete 1 thì em tìm hiểu mãi chưa chưa biết nó là gì, (2) nhưng em thử thấy bỏ đi nó vẫn vậy.

(1) Mà nếu bạn biết rồi cũng đừng nên xài như vậy, mình khuyên bạn đó!

Nó giống như vay tiền đi buôn vậy đó bạn! Nhiều bất trắc dễ gặp khi tay nghề ta chưa cao.

(2) Không đâu, có khi lúc này, có khi lúc khác à nha! Vì bạn chưa gặp mà thôi, chứ thấy quan tài là đỗ lệ liền à.
 
Upvote 0
(1) Mà nếu bạn biết rồi cũng đừng nên xài như vậy, mình khuyên bạn đó!

.
Em nghĩ ngược lại đấy sư phụ à!
Nhũng hằng số xlUp, xlDown... vân vân.. chỉ có thể hoạt động được trong môi trường Excel
Hay nói chung, hằng số của 1 Reference nào tạo ra thì code chỉ có thể hiểu được khi gọi chính Reference ấy thôi
Lấy ví dụ: Anh gọi Scripting Runtime (bằng cách check mục "Microsoft Scripting Runtime" trong Tools\References) rồi chạy code dưới đây
Mã:
With New Scripting.FileSystemObject
  .OpenTextFile "Duong dan file", [COLOR=#ff0000][B]ForReading[/B][/COLOR]
End With
Cái thằng màu đỏ ForReading ấy là hằng số và code chỉ có thể hiểu được khi gọi Scripting Runtime
Đặt trường hợp mang code sang máy khác, người ta không muốn gọi Scripting Runtime bằng cách check References thì sẽ viết thế này:
Mã:
With CreateObject("Scripting.FileSystemObject")
  .OpenTextFile "Duong dan file", [COLOR=#ff0000][B]ForReading[/B][/COLOR]
End With
Code lỗi này lập tức thì nó chẳng hiểu ForReading là cái giống gì cả
Trong trường hợp này, tốt nhất phải thuộc lòng giá trị hằng số ấy là bao nhiêu rồi ghi trực tiếp vào code:
Mã:
With CreateObject("Scripting.FileSystemObject")
   .OpenTextFile "Duong dan fil", [COLOR=#ff0000][B]1[/B][/COLOR]
 End With
Hoặc cách khác
Mã:
[B][COLOR=#ff0000]Public Const ForReading = 1[/COLOR][/B]
Sub Test()
With CreateObject("Scripting.FileSystemObject")
  .OpenTextFile "Duong dan fil", [B][COLOR=#ff0000]ForReading[/COLOR][/B]
End With
End Sub
Lập trình VB hoặc VBA khi dùng các hàm API hổ trợ người ta vẫn dùng cách này đấy sư phụ à
-----------------------
Sư phụ có nghĩ đến tình huống người ta viết code từ VB6, gọi Excel bằng cách CreateObject("Excel.Application") gì gì đó thì làm cách nào code nó hiểu xlUp, xlDown là cái gì đây?
Kết luận cuối cùng: Phải luôn thuộc lòng các giá trị của hằng số để có thể làm việc trên bất cứ môi trường nào (không riêng gì Excel)
 
Lần chỉnh sửa cuối:
Upvote 0
Thưa thày Code viết theo cách mới
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim CrRng As Range
  If Not Intersect(Range("C1:C2"), Target) Is Nothing Then
    Range("A5:G1000").Clear
    Set CrRng = Range("C1:C2")
    With Sheets("Data")
      With .Range(.[A1], .[A65536].End(xlUp)).Resize(, 7)
        .AdvancedFilter 2, CrRng, Range("A4:E4")
      End With
    End With
  End If
End Sub
Như thế thì tại sao máy nó hiểu là xóa 2 cột D và E đi mà không phải là xóa các cột khác?
 
Upvote 0
Thưa thày Code viết theo cách mới
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim CrRng As Range
  If Not Intersect(Range("C1:C2"), Target) Is Nothing Then
    Range("A5:G1000").Clear
    Set CrRng = Range("C1:C2")
    With Sheets("Data")
      With .Range(.[A1], .[A65536].End(xlUp)).Resize(, 7)
        .AdvancedFilter 2, CrRng, Range("A4:E4")
      End With
    End With
  End If
End Sub
Như thế thì tại sao máy nó hiểu là xóa 2 cột D và E đi mà không phải là xóa các cột khác?
Đó là tính năng của Advanced Filter mà tôi mới biết thời gian gần đây (nhở xem bài của nghiaphuc)
Có nghĩa là:
- Nếu bạn có dữ liệu 6 cột (với tiêu đề cho trước)
- Khi lọc ra nơi khác và không nói gì thì Advanced Filter sẽ lọc hết 6 cột ấy
- Tại nơi đặt kết quả, nếu bạn ghi sẵn 4 tiêu đề của 4 cột thì khi lọc ra, Advanced Filter sẽ ngầm hiểu rằng bạn chỉ muốn lấy 4 cột (2 cột còn lại không lấy)
-----------
Tóm lại, để lọc theo cách có chọn lựa kiểu này thì điều tiên quyết là bạn phải ghi trước ra nơi đặt kết quả những tên tiêu đề cột nào mà bạn muốn lấy
 
Upvote 0
Cho em hỏi về Code lọc dữ liệu với ah:

PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim CrRng As Range
  If Not Intersect(Range("C1:C2"), Target) Is Nothing Then
    Range("A4:G1000").Clear
    Set CrRng = Range("C1:C2")
    With Sheets("Data")
      With .Range(.[A1], .[A65536].End(xlUp)).Resize(, 7)
        .AdvancedFilter 2, CrRng, Range("A4")
      End With
    End With
    Range([A4], [A65536].End(xlUp)).Resize(, 2).Offset(, 3).Delete 1
  End If
End Sub

xin kính mong được giúp đỡ
------------
Dấu <> ở ô C2 sheets(Detail) có phải là dạng toán tử không (tại sao không là ký tự khác?) hay nó thể hiện là chỉ lọc những ô không phải là ô rỗng tại cột TK Nợ, TK Có (tức cột D, E) ?
Trong Delete 1 thì 1 là gì ah?
tôi thì hay chế code của NDU
theo tôi thì như chế đoạn như vầy
Range([A4], [A65536].End(xlUp)).Resize(, 2).Offset(, 3).Delete 1
thành

Range([A4], [A65536].End(xlUp)).Resize(, 4).Offset(, 3).Value = Range([A4], [A65536].End(xlUp)).Resize(, 4).Offset(, 5).Value
 
Upvote 0
Thày còn Link bài này không ah, nếu có thày cho em xin

(Em thấy kiểu này thày làm tương đối mới so với các bài em đã đọc về Advanced Filter, các bài trước vùng điều kiện 1 ô đầu tiên thường để trống)
 
Upvote 0
Thày còn Link bài này không ah, nếu có thày cho em xin
Chắc là bài này:
http://www.giaiphapexcel.com/forum/...-dữ-liệu-sang-sheet-khac-sau-khi-autofilter
(Seach cái ra ngay mà)
(Em thấy kiểu này thày làm tương đối mới so với các bài em đã đọc về Advanced Filter, các bài trước vùng điều kiện 1 ô đầu tiên thường để trống)
- Với vùng điều kiện của Advanced Filter, nếu cell thứ 2 là công thức thì cell thứ nhất buộc phải để trống (hoặc ghi cái gì đó miễn khác với tiêu đề dữ liệu)
- Với vùng điều kiện của Advanced Filter, nếu cell thứ 2 là 1 điều kiện cụ thể (dạng chuổi) thì cell thứ nhất bắt buộc phải có tên là 1 tiêu đề nào đó của dữ liệu
Thật ra trong Excel, ta có thể bấm F1, gõ từ khóa Advanced Filter vào để xem chi tiết
 
Upvote 0
Thưa thày tại sao em thay
PHP:
.AdvancedFilter 2, CrRng, Range("A4:E4")

bằng cái này
PHP:
.AdvancedFilter 2, CrRng, Range("A4:F4")

Nó báo lỗi, em không biết vì sao vì em chưa hiểu bản chất vấn đề lắm
 
Upvote 0
Thưa thày tại sao em thay
PHP:
.AdvancedFilter 2, CrRng, Range("A4:E4")

bằng cái này
PHP:
.AdvancedFilter 2, CrRng, Range("A4:F4")

Nó báo lỗi, em không biết vì sao vì em chưa hiểu bản chất vấn đề lắm

Câu lệnh AdvancedFilter 2, CrRng, Range("A4:F4") có nghĩa là:
- Dùng Advanced Filter lọc sang nơi khác
- Điều kiện lọc là CrRng
- Nơi đặt kết quả là Range("A4:F4")
Bạn có 2 lựa chọn về cách viết nơi đặt kết quả:
- Hoặc là xóa sạch vùng đặt kết quả (bao gồm tiêu đề) rồi thay Range("A4:F4") thành Range("A4") ---> Tức chỉ được phép ghi là 1 CELL
- Hoặc là phải ghi đầy đủ tiêu đề vào vùng A4:F4 (cell F4 không được để trống) thì mới dùng được code trên
 
Upvote 0
Em đã hiểu rồi, thì ra cách đặt trước vùng thì phải cho nó nhìn được Tên tiêu đề (của những cột cần lọc).

Em xin hỏi chút xíu nữa trong cách dùng của AdvancedFilter:
Nếu vùng điều kiện trong trường hợp ô đầu tiên (C1) là tên của tiêu đề cột, tức ô sau không dùng dưới dạng công thức mà dùng dưới dạng biểu thức (ký tự) thì: ô sau (C2) ngoài ký tự <>(khác rỗng), còn có ký tự nào khác hay dùng nữa không?

(em thử nghiệm cho một số ký tự khác như >...---> kết quả nó ra đều tương đương với None)
 
Upvote 0
Em đã hiểu rồi, thì ra cách đặt trước vùng thì phải cho nó nhìn được Tên tiêu đề (của những cột cần lọc).

Em xin hỏi chút xíu nữa trong cách dùng của AdvancedFilter:
Nếu vùng điều kiện trong trường hợp ô đầu tiên (C1) là tên của tiêu đề cột, tức ô sau không dùng dưới dạng công thức mà dùng dưới dạng biểu thức (ký tự) thì: ô sau (C2) ngoài ký tự <>(khác rỗng), còn có ký tự nào khác hay dùng nữa không?

(em thử nghiệm cho một số ký tự khác như >...---> kết quả nó ra đều tương đương với None)
Có thể dùng bất cứ chuổi gì, miễn sao "nó" hiểu
Ví dụ
- Cell C2 bạn ghi 156 ---> Nghĩa là lọc thằng nào ở cột trùng với tiêu đề C1 và điều kiện là =156
- Cell C2 bạn ghi >100 ---> Nghĩa là lọc thằng nào ở cột trùng với tiêu đề C1 và điều kiện là >100
--------------
Còn chữ None, chẳng qua ghi thế cho gợi nhớ, bạn có thể thay nó bằng bất cứ chữ gì (chữ xóa hết chẳng hạn) miễn sao chữ ấy không có trong dữ liệu ---> Mục địch của ta là xóa hết mà
 
Upvote 0
Cho em hỏi trong Code sau

PHP:
Sub Xoadong()
 Dim Rng As Range
 Set Rng = [A1].CurrentRegion
 Rng.Value = Rng.Value
 Rng.AutoFilter Field:=3, Criteria1:="0"
 Rng.SpecialCells(12).EntireRow.Delete
End Sub

tại sao lại có dòng Rng.Value = Rng.Value nghĩa là gì ah?
 
Upvote 0
Cho em hỏi trong Code sau

PHP:
Sub Xoadong()
 Dim Rng As Range
 Set Rng = [A1].CurrentRegion
 Rng.Value = Rng.Value
 Rng.AutoFilter Field:=3, Criteria1:="0"
 Rng.SpecialCells(12).EntireRow.Delete
End Sub

tại sao lại có dòng Rng.Value = Rng.Value nghĩa là gì ah?
Chắc là sợ trong Rng có công thức, sau khi xóa dòng xong nó "chạy loạn" chăng, nên trước khi xóa, dùng câu lệnh Rng.Value = Rng.Value để chuyển công thức thành giá trị ấy mà
 
Upvote 0
Cho em hỏi -1E+308 là gì

Trong Code
PHP:
Function MaxIf(ByVal CritArr, ByVal Criteria, ByVal ResArr) As Double
  Dim TmpMax As Double, TmpCrit, TmpRes, i As Long, j As Long
  TmpMax = -1E+308
  TmpCrit = CritArr: TmpRes = ResArr
  For i = LBound(TmpCrit, 1) To UBound(TmpCrit, 1)
    For j = LBound(TmpCrit, 2) To UBound(TmpCrit, 2)
      If TmpCrit(i, j) = Criteria Then
        If TmpRes(i, j) > TmpMax Then TmpMax = TmpRes(i, j)
      End If
    Next
  Next
  MaxIf = TmpMax
End Function

Cho em hỏi -1E+308 là gì, liệu có phải là số nhỏ nhất không, nhỡ may cột A có số nào nhỏ hơn nó thì sao

(Tại sao không phải là -1E+309... gì đó?)
 
Upvote 0
Trong Code
PHP:
Function MaxIf(ByVal CritArr, ByVal Criteria, ByVal ResArr) As Double
  Dim TmpMax As Double, TmpCrit, TmpRes, i As Long, j As Long
  TmpMax = -1E+308
  TmpCrit = CritArr: TmpRes = ResArr
  For i = LBound(TmpCrit, 1) To UBound(TmpCrit, 1)
    For j = LBound(TmpCrit, 2) To UBound(TmpCrit, 2)
      If TmpCrit(i, j) = Criteria Then
        If TmpRes(i, j) > TmpMax Then TmpMax = TmpRes(i, j)
      End If
    Next
  Next
  MaxIf = TmpMax
End Function

Cho em hỏi -1E+308 là gì, liệu có phải là số nhỏ nhất không, nhỡ may cột A có số nào nhỏ hơn nó thì sao

(Tại sao không phải là -1E+309... gì đó?)

Đúng ra số -9.99999999999999E+307 mới là nhỏ nhất
Thử gõ số -9.99999999999999E+307 vào A1
Tại B1, gõ công thức = A1-1
Tại C1, gõ công thức =A1=B1 xem ra kết quả bao nhiêu?
Dù bạn có trừ bớt bao nhiêu thì B1 cũng không sao nhỏ hơn A1 được
Ẹc... Ẹc...
 
Upvote 0
Status
Không mở trả lời sau này.
Web KT

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

Back
Top Bottom