Copy dữ liệu trong 1 sheet dùng VBA

  • Thread starter Thread starter NQ_AT
  • Ngày gửi Ngày gửi
Liên hệ QC

NQ_AT

Thành viên chính thức
Tham gia
9/12/14
Bài viết
68
Được thích
9
Thân chào các bạn,
Mình mới mày mò VBA và viết ra code để copy dữ liệu trong 1 sheet, với sheet 1, khi Range là 1 cột thì dùng offset chạy ok, nhưng qua sheet 2, khi tập hợp 2 Range thì ko biết set IF thế nào luôn, nó cứ chạy ào ào.

Mục đích là copy dữ liệu từ bảng 1 sang bảng 2 theo điều kiện:

- Nếu tại cột E những dòng nào có giá trị thì mới copy qua >>> cái này chưa giới hạn được

- Tại bảng 2, những ô nào highlight màu đỏ thì bỏ qua không cần copy đè lên. >> cái này ok rồi.

Nhờ các bạn xem giúp file và hướng dẫn giúp mình cách khắc phục nha.

Cảm ơn rất nhiều.
 

File đính kèm

Xin chào anh quanghai1969, và các anh GPE ( bữa giờ gọi bạn cũng hơi kì kì vì mình là người mới trên này) :)

Mong các anh hướng dẫn giúp chút xíu để mình tự phát triển code này.
1- trong code có đoạn
PHP:
For i = 1 To UBound(arr1)
    For j = 1 To UBound(Arr2, 2)
       If j <> 4 Then
      .
      .
      .
Vậy nếu mình muốn J khác cột 4 đến 6 thì phải khai báo thế nào?
2- Đụng tới phần tính toán trong mảng, mà tìm hoài chưa thấy tài liệu hướng dẫn, đây là trường hợp ngược lại của J (nếu J = cột 4 To 6 của Arr2)
PHP:
Else
If arr1(i,4) <> "" Then ' Cột số 4 của Arr1 là cột số lượng
     arr1(i,5).value = Arr2(i,5).value * arr1(i,4).value
     arr1(i,6).value = Arr2(i,6).value * arr1(i,4).value
End If

nó báo lỗi, hình như cái này đang là mảng nên mình ko cho value được, mà hiện tại ko biết làm thế nào, mong các anh tiếp sức.
Viết thế này If J = 4 or J = 5 or J =6 Then
Hoặc If J <> 4 or J <> 5 or J <> 6 Then
Thử sẽ biết nên chọn cái nào
.......................
Mảng không được có cái đuôi mọc ra phía sau vậy đâu. Bạn phải làm giống mọi người chứ.
 
Upvote 0
Viết thế này If J = 4 or J = 5 or J =6 Then
Hoặc If J <> 4 or J <> 5 or J <> 6 Then
Thử sẽ biết nên chọn cái nào
.......................
Mảng không được có cái đuôi mọc ra phía sau vậy đâu. Bạn phải làm giống mọi người chứ.
Cảm ơn anh , vấn đề nằm ở chổ chưa có kiến thức VBA nên có ý tưởng mà ko biết dùng lệnh gì, biết mảng ko thể mọc đuôi nhưng bí quá gắn thêm đuôi cho nó thử thế nào. hjhjjh.
vừa bắt gặp bài này của anh, thấy nó cũng dùng mảng và cái Res gì đó, để ngâm cứu thử xem, thấy có dùng value trong mảng
PHP:
Sub loc()
Dim Data(), Res(), i, j, k
[A13:H5000].ClearContents
Data = Sheet1.Range(Sheet1.[AB9], Sheet1.[AB65536].End(3)).Resize(, 10).Value
ReDim Res(1 To UBound(Data), 1 To 8)
For i = 1 To UBound(Data)
   If Data(i, 1) >= [D5].Value Then
      If Data(i, 1) <= [D6].Value Then
         If [H7].Value = "" Then
            If Data(i, 9) = [H6].Value Or Data(i, 8) = [H6].Value Then
               k = k + 1
               Res(k, 1) = Data(i, 1)
               Res(k, 2) = Data(i, 2)
               Res(k, 3) = Data(i, 3)
               Res(k, 4) = Data(i, 5)
               Res(k, 5) = Data(i, 7)
               If Data(i, 8) = [H6].Value Then Res(k, 6) = Data(i, 9)
               If Data(i, 9) = [H6].Value Then Res(k, 6) = Data(i, 8)
               If Data(i, 8) = [H6].Value Then Res(k, 7) = Data(i, 10)
               If Data(i, 9) = [H6].Value Then Res(k, 8) = Data(i, 10)
            End If
         Else
            If Data(i, 6) = [H7].Value Then
                If Data(i, 9) = [H6].Value Or Data(i, 8) = [H6].Value Then
                  k = k + 1
                  Res(k, 1) = Data(i, 1)
                  Res(k, 2) = Data(i, 2)
                  Res(k, 3) = Data(i, 3)
                  Res(k, 4) = Data(i, 5)
                  Res(k, 5) = Data(i, 7)
                  If Data(i, 8) = [H6].Value Then Res(k, 6) = Data(i, 9)
                  If Data(i, 9) = [H6].Value Then Res(k, 6) = Data(i, 8)
                  If Data(i, 8) = [H6].Value Then Res(k, 7) = Data(i, 10)
                  If Data(i, 9) = [H6].Value Then Res(k, 8) = Data(i, 10)
               End If
            End If
         End If
      End If
   End If
Next
k = k + 1
Res(k, 7) = "=sum(R13C:R[-1]C)"
Res(k, 8) = "=sum(R13C:R[-1]C)"
[A13].Resize(k, 8) = Res
End Sub
 
Upvote 0
... thấy nó cũng dùng mảng và cái Res gì đó, để ngâm cứu thử xem, thấy có dùng value trong mảng
...

Code trên được viết theo tinh thần VBScript, tức là lúc khai báo thì mọi biến đều thuộc dạng Variant. Bao giờ được gán trị thì biến mới biết dạng thực của nó.

Cái mà mấy bạn gọi là "cái đuôi", theo đúng từ ngữ lập trình thì nó là thành phần của lớp (class member). Thành phần của lớp được chia ra làm hai loại là hàm/phương thức và thuộc tính.

Chỉ có những loại dữ liệu dạng Object lấy từ một lớp phức tạp mới có thành phần. Khi khai báo định nghĩa một lớp phức tạp, người thiết kế cũng đồng thời định nghĩa các thành phần. Các loại dữ liệu như Integer, Long, Float, Double, String, ... là loại dữ liệu căn bản của ngôn ngữ VBA. Những loại này không phải là phức tạp nên không có thành phần. Loại dữ liệu như WorkSheet, Range, ... là loại dữ liệu phức tạp cho nên chúng có thành phần. Và Value là thành phần dạng thuộc tính của Range.

Trong hầu hết các ngôn ngữ lập trình hướng đối tượng, dấu chấm là ký hiệu gọi thành phần của lớp. Vì vậy, nếu rangeGiDo là một range thì "rangeGiDo.Value" là biểu thức truy cứu thộc tính Value của rangeGiDo

Mảng chỉ là một dãy dữ liệu giống kiểu và xếp kế nhau. Chính mảng không phải là một lớp cho nên không có thành phần. Mặt khác, vì mảng là một dãy dữ liệu gồm nhiều phần tử cho nên hầu như tất cả các ngôn ngữ lập trình đều có một con toán truy cập phân tử mảng. Trong VBA, con toán này là dây ngoặc (). Nếu Arr là mảng thì biểu thức Arr(i) truy cập phần tử thứ i của Arr.

Câu hỏi cuối cúng của bạn: tại sao có mảng vẫn thấy có "cái đuôi"?
Mảng chỉ là một dãy phần tử. Mỗi phần tử của mảng vẫn có thể là ở dạng một lớp phức tạp. Trường hợp đó, chúng có quyền dùng "cái đuôi".

Tuy nhiên trong code mà bạn dẫn ra, các mảng tuy khai báo được mặc định phần tử dạng Variant nhưng sau khi gán trị thì chúng trở thành String. Dữ liệu dạng String không có thuộc tính Value.

Lưu ý: ngoài các tính chất phức tạp, Range cũng đồng thời bao gồm tất cả những tính chất của mảng, cho nên cũng có khi người ta gọi Range là mảng.
 
Lần chỉnh sửa cuối:
Upvote 0
Code trên được viết theo tinh thần VBScript, tức là lúc khai báo thì mọi biến đều thuộc dạng Variant. Bao giờ được gán trị thì biến mới biết dạng thực của nó.

Cái mà mấy bạn gọi là "cái đuôi", theo đúng từ ngữ lập trình thì nó là thành phần của lớp (class member). Thành phần của lớp được chia ra làm hai loại là hàm/phương thức và thuộc tính.

Chỉ có những loại dữ liệu dạng Object lấy từ một lớp phức tạp mới có thành phần. Khi khai báo định nghĩa một lớp phức tạp, người thiết kế cũng đồng thời định nghĩa các thành phần. Các loại dữ liệu như Integer, Long, Float, Double, String, ... là loại dữ liệu căn bản của ngôn ngữ VBA. Những loại này không phải là phức tạp nên không có thành phần. Loại dữ liệu như WorkSheet, Range, ... là loại dữ liệu phức tạp cho nên chúng có thành phần. Và Value là thành phần dạng thuộc tính của Range.

Trong hầu hết các ngôn ngữ lập trình hướng đối tượng, dấu chấm là ký hiệu gọi thành phần của lớp. Vì vậy, nếu rangeGiDo là một range thì "rangeGiDo.Value" là biểu thức truy cứu thộc tính Value của rangeGiDo

Mảng chỉ là một dãy dữ liệu giống kiểu và xếp kế nhau. Chính mảng không phải là một lớp cho nên không có thành phần. Mặt khác, vì mảng là một dãy dữ liệu gồm nhiều phần tử cho nên hầu như tất cả các ngôn ngữ lập trình đều có một con toán truy cập phân tử mảng. Trong VBA, con toán này là dây ngoặc (). Nếu Arr là mảng thì biểu thức Arr(i) truy cập phần tử thứ i của Arr.

Câu hỏi cuối cúng của bạn: tại sao có mảng vẫn thấy có "cái đuôi"?
Mảng chỉ là một dãy phần tử. Mỗi phần tử của mảng vẫn có thể là ở dạng một lớp phức tạp. Trường hợp đó, chúng có quyền dùng "cái đuôi".

Tuy nhiên trong code mà bạn dẫn ra, các mảng tuy khai báo được mặc định phần tử dạng Variant nhưng sau khi gán trị thì chúng trở thành String. Dữ liệu dạng String không có thuộc tính Value.

Lưu ý: ngoài các tính chất phức tạp, Range cũng đồng thời bao gồm tất cả những tính chất của mảng, cho nên cũng có khi người ta gọi Range là mảng.

Cảm ơn anh VetMini,

Đọc qua nhưng chưa đủ nội công để hiểu hết, hiểu được 60%. hjhjh
Nhưng anh có nói, dữ liệu kiểu String, vậy nếu mình dùng CDbl (String) để chuyển sang Number thì có dùng Vaue được hok?
Mong anh cho VD nào gần gần để mình hiểu thêm nha.
 
Upvote 0
Mong các anh xem giúp file, mình bó tay rồi, phần tính toán trong mảng ko biết tí gì, mà đưa về range cũng bị báo lỗi.

Hiện tại file này mình đã cho chạy ok 1 phần rồi, chỉ còn phần tính toán mình có nêu yêu cầu trong file.

PHP:
Sub DoanMo()
Dim arr1(), Arr2(), i, j, k1, k2, Rng
arr1 = [E5:N24].Value
Arr2 = [Q5:Y24].Value
For i = 1 To UBound(arr1)
    For j = 1 To UBound(Arr2, 2)
                     If arr1(i, 1) <> "" Then               
                        'If arr1(i, k + 1) <> "" Then
                             If Cells(i + 4, j + 5).Font.ColorIndex <> 3 Then
                                   If j <> 5 And j <> 6 And j <> 7 And j <> 8 Then
                                       arr1(i, j + 1) = Arr2(i, j)
                                    Else 
                                            'phan nay botay      
              
                                  End If
                             End If
                      End If
           Next
   Next
[E5:N24].Value = arr1
End Sub
Mong các anh trợ giúp code còn lại để mình học hỏi thêm nha.
 

File đính kèm

Upvote 0
Khả năng của bạn chưa đủ để đọc và hiểu code của người khác. Nhất là code của bạn quanghai1969 chuyên về tốc độ và sự ngắn gọn, bạn không nên chỉnh sửa code này vì chẳng những khó mà còn rất nguy hiểm.

Nếu muốn học code, bạn nên tìm những code chuyên về dễ hiểu và dễ chỉnh sửa. Loại code này ít sử dụng những thủ thuật chuyên về cải tiến tốc độ. Và nếu có những phần khó thì những phần này cũng được tách rời ra thảnh hàm/sub riêng biệt. Chủ yếu là bạn chỉ cần và chỉ nên sửa những chỗ dễ hiểu.
 
Upvote 0
Khả năng của bạn chưa đủ để đọc và hiểu code của người khác. Nhất là code của bạn quanghai1969 chuyên về tốc độ và sự ngắn gọn, bạn không nên chỉnh sửa code này vì chẳng những khó mà còn rất nguy hiểm.

Nếu muốn học code, bạn nên tìm những code chuyên về dễ hiểu và dễ chỉnh sửa. Loại code này ít sử dụng những thủ thuật chuyên về cải tiến tốc độ. Và nếu có những phần khó thì những phần này cũng được tách rời ra thảnh hàm/sub riêng biệt. Chủ yếu là bạn chỉ cần và chỉ nên sửa những chỗ dễ hiểu.

Vâng, mình đang cố gắng hết sức, Vậy trước mắt nhờ các anh làm giúp mình cho xong cái form này nha,vì form cần copy tới khoảng 5000 dòng nên code của anh quanghai1969 là rất tuyệt, vì tuần sau mình phải hoàn thiện form này rồi. Không phải mình lười mà vì trình độ chưa tới nên các anh thông cảm.

Nếu yêu cầu trong file chưa rõ thì các anh phản hồi lại để mình bổ sung liền nha.

Rất cảm ơn sự giúp đỡ nhiệt tình của các anh.
 
Upvote 0
Vâng, mình đang cố gắng hết sức, Vậy trước mắt nhờ các anh làm giúp mình cho xong cái form này nha,vì form cần copy tới khoảng 5000 dòng nên code của anh quanghai1969 là rất tuyệt, vì tuần sau mình phải hoàn thiện form này rồi. Không phải mình lười mà vì trình độ chưa tới nên các anh thông cảm.

Nếu yêu cầu trong file chưa rõ thì các anh phản hồi lại để mình bổ sung liền nha.

Rất cảm ơn sự giúp đỡ nhiệt tình của các anh.
Mình không nghĩ là sẽ có ai đó lại đi ngồi dò từng ô rồi tô đỏ tô xanh, rồi lại chạy code.
Dữ liệu của bạn nhìn không thật nên không hứng thú nghiên cứu.
 
Upvote 0
Vâng, mình đang cố gắng hết sức, Vậy trước mắt nhờ các anh làm giúp mình cho xong cái form này nha,vì form cần copy tới khoảng 5000 dòng nên code của anh quanghai1969 là rất tuyệt, vì tuần sau mình phải hoàn thiện form này rồi. Không phải mình lười mà vì trình độ chưa tới nên các anh thông cảm.

Nếu yêu cầu trong file chưa rõ thì các anh phản hồi lại để mình bổ sung liền nha.

Rất cảm ơn sự giúp đỡ nhiệt tình của các anh.
Mình tải thử file ở bài 26 thấy nhiều hình vẽ lằng nhằng khó hiểu quá. Bạn nên bỏ hết các hình vẽ đi, ghi rõ yêu cầu trong 1 sheet, có thể thêm kết quả cần làm trong sheet khác để dễ so sánh. Dữ liệu thì chỉ cần 10-20 dòng thôi.
 
Upvote 0
Mình không nghĩ là sẽ có ai đó lại đi ngồi dò từng ô rồi tô đỏ tô xanh, rồi lại chạy code.
Dữ liệu của bạn nhìn không thật nên không hứng thú nghiên cứu.

Cái này là đặt thù công việc bên mình đó anh.

Vì mình làm dự toán khối lượng, phải làm từng dòng, và trong các trường hợp khác nhau thì mình sẽ điều chỉnh giá( hoặc các thông tin về hàng hóa) khác nhau, khi điều chỉnh phải highlight màu đỏ lên, lúc đó giá ( hoặc các thông tin về hàng hóa) sẽ ko chạy theo data nữa. Đó là cách làm thực tế, mình muốn các anh giúp nên đâu có đưa form tào lao lên được, mong anh quanghai1969 hiểu cho.
Hiện tại mình chỉ còn vướng phần tính toán thôi, mong anh quanghai1969 xem xét giúp.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình tải thử file ở bài 26 thấy nhiều hình vẽ lằng nhằng khó hiểu quá. Bạn nên bỏ hết các hình vẽ đi, ghi rõ yêu cầu trong 1 sheet, có thể thêm kết quả cần làm trong sheet khác để dễ so sánh. Dữ liệu thì chỉ cần 10-20 dòng thôi.

Cái dấu mũi tên mình chỉ từ bảng 1 sang bảng 2 phải ko anh? ý là mình muốn nói copy từ bảng 1 sang bảng 2( Anh chỉ cần xem ở Sheet 3 thôi)

OK, để mình làm cái kết quả trong sheet nữa rồi up lại nha.
 
Upvote 0
Cái dấu mũi tên mình chỉ từ bảng 1 sang bảng 2 phải ko anh? ý là mình muốn nói copy từ bảng 1 sang bảng 2( Anh chỉ cần xem ở Sheet 3 thôi)

OK, để mình làm cái kết quả trong sheet nữa rồi up lại nha.
Bài này phải dùng chiêu khác, đó là Select Case.
PHP:
If Arr1(i,1) <> "" Then
      For j = 2 To 10
         Select Case j
         Case 2, 3, 4, 5, 10
                 'xử lý như lúc đầu
         Case 6
               'xử lý cái mới chỗ này
         End Select
      Next
End If
 
Lần chỉnh sửa cuối:
Upvote 0
Bài này phải dùng chiêu khác, đó là Select Case.
PHP:
      For j = 2 To 10
         Select Case j
         Case 2, 3, 4, 5, 10
                 'xử lý như lúc đầu
         Case 6
               'xử lý cái mới chỗ này
         End Select
      Next

Xin anh quanghai1969 giúp luôn code cho trót, hiện tại đang bị tẩu hỏa nhập ma sau khi lọt vào ma trận mảng.

Các điều kiện đưa ra là theo thực tế, anh quanghai1969 yên tâm nha.
 
Upvote 0
Xin anh quanghai1969 giúp luôn code cho trót, hiện tại đang bị tẩu hỏa nhập ma sau khi lọt vào ma trận mảng.

Các điều kiện đưa ra là theo thực tế, anh quanghai1969 yên tâm nha.
Thử code này coi đúng ý không. Cũng thấy hơi mù mờ
PHP:
Sub abc()
Dim Sarr(), Darr(), i, j, x, usd
Sarr = Range("Q5", [Y65536].End(3)).Value
Darr = Range("E5", [N65536].End(3)).Value
usd = [N2].Value
For i = 1 To UBound(Darr)
   If Darr(i, 1) <> "" Then
      For j = 2 To 10
         Select Case j
         Case 2, 3, 4, 5, 10
            If Darr(i, j) = "" Then
               Darr(i, j) = Sarr(i, j - 1)
            Else
               If Cells(i + 4, j + 4).Font.ColorIndex <> 3 Then
                  Darr(i, j) = Sarr(i, j - 1)
               End If
            End If
         Case 6
            If Darr(i, j) <> "" Then
               For x = 7 To 9
                  Darr(i, x) = Sarr(i, x - 1) * Darr(i, j) / usd
               Next
            End If
         End Select
      Next
   End If
Next
Range("E5", [N65536].End(3)).Value = Darr
End Sub
 
Upvote 0
Thử code này coi đúng ý không. Cũng thấy hơi mù mờ
PHP:
Sub abc()
Dim Sarr(), Darr(), i, j, x, usd
Sarr = Range("Q5", [Y65536].End(3)).Value
Darr = Range("E5", [N65536].End(3)).Value
usd = [N2].Value
For i = 1 To UBound(Darr)
   If Darr(i, 1) <> "" Then
      For j = 2 To 10
         Select Case j
         Case 2, 3, 4, 5, 10
            If Darr(i, j) = "" Then
               Darr(i, j) = Sarr(i, j - 1)
            Else
               If Cells(i + 4, j + 4).Font.ColorIndex <> 3 Then
                  Darr(i, j) = Sarr(i, j - 1)
               End If
            End If
         Case 6
            If Darr(i, j) <> "" Then
               For x = 7 To 9
                  Darr(i, x) = Sarr(i, x - 1) * Darr(i, j) / usd
               Next
            End If
         End Select
      Next
   End If
Next
Range("E5", [N65536].End(3)).Value = Darr
End Sub
Tuyệt vời anh ơi, code chạy quá ok,
Nhưng sao nó chỉ chạy tới dòng 18 thôi anh? có bấm thế nào cũng ko thể chạy hơn dòng 18
 
Upvote 0
Tuyệt vời anh ơi, code chạy quá ok,
Nhưng sao nó chỉ chạy tới dòng 18 thôi anh? có bấm thế nào cũng ko thể chạy hơn dòng 18
Thay đám rừng này vào thử coi
PHP:
Sub abc()
Dim Sarr(), Darr(), i, j, x, usd
Sarr = Range("Q5", [Y65536].End(3)).Value
Darr = Range("E5", [Q65536].End(3).Offset(, -3)).Value
usd = [N2].Value
For i = 1 To UBound(Darr)
   If Darr(i, 1) <> "" Then
      For j = 2 To 10
         Select Case j
         Case 2, 3, 4, 5, 10
            If Darr(i, j) = "" Then
               Darr(i, j) = Sarr(i, j - 1)
            Else
               If Cells(i + 4, j + 4).Font.ColorIndex <> 3 Then
                  Darr(i, j) = Sarr(i, j - 1)
               End If
            End If
         Case 6
            If Darr(i, j) <> "" Then
               For x = 7 To 9
                  Darr(i, x) = Sarr(i, x - 1) * Darr(i, j) / usd
               Next
            End If
         End Select
      Next
   End If
Next
Range("E5", [Q65536].End(3).Offset(, -3)).Value = Darr
End Sub
 
Upvote 0
Thay đám rừng này vào thử coi
PHP:
Sub abc()
Dim Sarr(), Darr(), i, j, x, usd
Sarr = Range("Q5", [Y65536].End(3)).Value
Darr = Range("E5", [Q65536].End(3).Offset(, -3)).Value
usd = [N2].Value
For i = 1 To UBound(Darr)
   If Darr(i, 1) <> "" Then
      For j = 2 To 10
         Select Case j
         Case 2, 3, 4, 5, 10
            If Darr(i, j) = "" Then
               Darr(i, j) = Sarr(i, j - 1)
            Else
               If Cells(i + 4, j + 4).Font.ColorIndex <> 3 Then
                  Darr(i, j) = Sarr(i, j - 1)
               End If
            End If
         Case 6
            If Darr(i, j) <> "" Then
               For x = 7 To 9
                  Darr(i, x) = Sarr(i, x - 1) * Darr(i, j) / usd
               Next
            End If
         End Select
      Next
   End If
Next
Range("E5", [Q65536].End(3).Offset(, -3)).Value = Darr
End Sub

Hoảng thật, hơn 5000 dòng mà 1s là xong vửa copy và vừa tính toán luôn.
.
Cảm ơn anh quanghai1969 nhiều nha.
 
Upvote 0
Chào các bác các chú cháu muốn copy dữ liệu (không bao gồm công thức ) lần lượt từng dòng một từ hàng 2 tới hàng 21 vào hàng 29(đã có săn công thức) sau mỗi lần bấm nút thì VBA này chỉnh sao ạ
 

File đính kèm

Upvote 0
Chào mọi người, em muốn copy toàn bô sheet 1 sang sheet2 mà trong đó các công thức chức năng không đổi. Việc copy này dc thực hiện khi nhấn nút thêm đối tượng thì tạo ra sheet mới.

Cám ơn mọi người rất nhiều
 
Upvote 0
Web KT

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

Back
Top Bottom