Hỏi Về Đổi giá trị B sang A và A sang B? (1 người xem)

  • Thread starter Thread starter nad582
  • Ngày gửi Ngày gửi

Người dùng đang xem chủ đề này

nad582

Thành viên thường trực
Tham gia
7/6/11
Bài viết
317
Được thích
48
Chào các a(c) trong GPE, e có bài tập sau xin a(c) chỉ dạy:
View attachment 125528
từ hình trên, b là chiều rộng, a là chiều dài
cho i đi từ I14 đến I65000 và j đi từ J14 đến J65000 nếu I > J thì đổi giá trị J sang I và nguợc lại.
Tóm lại là dò từ trên xuống nếu chiều rông nhỏ hơn chiều dài thì đổi giá trị chiều rộng sang chiều dài và ngược lại(nếu bằng nhau thi giữ nguyên hoặc đổi cũng ko sao). làm sao giá trị chiều dài luôn lớn hơn hoặc bằng chiều rộng.
Lưu ý: chỉ đổi giá trị (chứ không đổi Ô hay đổi cột)
kết quả ví dụ
View attachment 125530
chân thành cảm ơn
 
Chào các a(c) trong GPE, e có bài tập sau xin a(c) chỉ dạy:
View attachment 125528
từ hình trên, b là chiều rộng, a là chiều dài
cho i đi từ I14 đến I65000 và j đi từ J14 đến J65000 nếu I > J thì đổi giá trị J sang I và nguợc lại.
Tóm lại là dò từ trên xuống nếu chiều rông nhỏ hơn chiều dài thì đổi giá trị chiều rộng sang chiều dài và ngược lại(nếu bằng nhau thi giữ nguyên hoặc đổi cũng ko sao). làm sao giá trị chiều dài luôn lớn hơn hoặc bằng chiều rộng.
Lưu ý: chỉ đổi giá trị (chứ không đổi Ô hay đổi cột)
kết quả ví dụ
View attachment 125530
chân thành cảm ơn
Bạn tập viết code đi. Gợi ý cho bạn là dùng for next. Chịu khó viết code mới tiến bộ được.
 
Upvote 0
Vậy khai báo biến i và j thế nào vậy a!!

thử vậy xem :
Mã:
Sub GPE()
    Dim tmpArr, dB#, dH#
        tmpArr = Range("I14", [J65536].End(3))
        For i = 1 To UBound(tmpArr, 1)
            dB = tmpArr(i, 1):  dH = tmpArr(i, 2)
            If dB <> vbNull Then
                If dB > dH Then
                    tmpArr(i, 1) = dH:   tmpArr(i, 2) = dB
                End If
            End If
        Next
        Range("I14:J14").Resize(i - 1) = tmpArr
End Sub
 
Upvote 0
Vậy khai báo biến i và j thế nào vậy a!!
Thử đoạn code này xem sao:
Mã:
Public Sub doi()
Dim arr(), kq(), i as long
arr = Sheet1.Range("I14:J" & Sheet1.Range("J65500").End(xlUp).Row)
ReDim kq(1 To UBound(arr, 1), 1 To 2)


For i = 1 To UBound(arr, 1)
    If arr(i, 2) <= arr(i, 1) Then
        kq(i, 1) = arr(i, 1)
        kq(i, 2) = arr(i, 2)
    Else
        kq(i, 1) = arr(i, 2)
        kq(i, 2) = arr(i, 1)
    End If
Next i
        Sheet1.Range("I14").Resize(UBound(arr, 1), 2).Value = kq
End Sub
 
Upvote 0
Anh dùng thuật toán hoán vị nhé. Tạo một biến để lưu dữ liệu tạm thời rồi dùng phép gán.
 
Upvote 0
Thử đoạn code này xem sao:
Mã:
Public Sub doi()
Dim arr(), kq(), i as long
arr = Sheet1.Range("I14:J" & Sheet1.Range("J65500").End(xlUp).Row)
ReDim kq(1 To UBound(arr, 1), 1 To 2)


For i = 1 To UBound(arr, 1)
    If arr(i, 2) <= arr(i, 1) Then
        kq(i, 1) = arr(i, 1)
        kq(i, 2) = arr(i, 2)
    Else
        kq(i, 1) = arr(i, 2)
        kq(i, 2) = arr(i, 1)
    End If
Next i
        Sheet1.Range("I14").Resize(UBound(arr, 1), 2).Value = kq
End Sub
Sao bạn lại làm cho tình hình trở nên "khuất tạp" quá vậy ?
chọn vùng dữ liệu rồi chạy code sau là đủ
Mã:
Sub doi()
For Each r In Selection.Rows
If r.Cells(1) < r.Cells(2) Then
t = r.Cells(1)
r.Cells(1) = r.Cells(2)
r.Cells(2) = t
End If
Next
End Sub
 
Upvote 0
Sao bạn lại làm cho tình hình trở nên "khuất tạp" quá vậy ?
chọn vùng dữ liệu rồi chạy code sau là đủ
Mã:
Sub doi()
For Each r In Selection.Rows
If r.Cells(1) < r.Cells(2) Then
t = r.Cells(1)
r.Cells(1) = r.Cells(2)
r.Cells(2) = t
End If
Next
End Sub
Tôi thấy code của tôi rất dễ hiểu, tôi chỉ thấy khó hiểu ở từ "khuất tạp" mà bạn viết và ở cái nick mà bạn chọn để dùng thôi.
Chào mừng bạn "2 Lúa miền tây" đã thay tên đổi họ!
 
Upvote 0
Tôi thấy code của tôi rất dễ hiểu, tôi chỉ thấy khó hiểu ở từ "khuất tạp" mà bạn viết và ở cái nick mà bạn chọn để dùng thôi.
Chào mừng bạn "2 Lúa miền tây" đã thay tên đổi họ!
dạng bài tập hoán đổi này nên làm theo cách của hai ló miền tây nó mới hợp lý

muốn đổi a và b cho nhau ta có
tmp =a
a=b
b=tmp
bi nhiêu đó thôi là đủ
 
Upvote 0
Sao bạn lại làm cho tình hình trở nên "khuất tạp" quá vậy ?
chọn vùng dữ liệu rồi chạy code sau là đủ
Mã:
Sub doi()
For Each r In Selection.Rows
[COLOR=#ff0000][B]If r.Cells(1) < r.Cells(2) Then[/B][/COLOR]
t = r.Cells(1)
r.Cells(1) = r.Cells(2)
r.Cells(2) = t
End If
Next
End Sub
Nếu dữ liệu so sánh trong bài chỉ là kiểu sô nguyên Long thì code trên không vấn đề .
Tuy nhiên mình cũng chia sẻ thêm :
*khi dùng điều kiện so sánh toán tử A < B phải xét đến 2 trường hợp:
-TH1: A , B là số liệu dạng chuỗi (str)
-TH2: A,B là dữ liệu kiểu số:
ví dụ : tại ô A1 : dữ liệu là '20.426789
tại ô B1 : dữ liệu là '40.426
Lúc này điều kiện if A1 > B1 luôn thỏa mãn tức là A1> B1 vì đây là so sánh chuỗi .
Tùy yêu cầucủa bài toán, mà ta xác định tiêu chí so sánh, vấn đề này luôn luôn phải được cân nhắc , nếu không kết quả bài toán sẽ hoàn toàn đi theo hướng khác !
 
Upvote 0
dạng bài tập hoán đổi này nên làm theo cách của hai ló miền tây nó mới hợp lý

muốn đổi a và b cho nhau ta có
tmp =a
a=b
b=tmp
bi nhiêu đó thôi là đủ
Nếu cứ dùng cách đó mà đánh từng ô trên sheet với nhiều ngàn dòng thì chậm. Dùng mảng sẽ nhanh hơn.
Tay trái cầm muỗng, tay phải cầm nĩa, muốn đổi qua lại với nhau có ít nhất 4 cách.

1. Cách 1: Bỏ cái muỗng tay trái xuống bàn (trung gian), chuyển cái nĩa từ tay phải qua tay trái, rồi tay phải lượm cái muỗng. Đây là cách chậm nhất.
2. Cách 2.1: Đưa muỗng qua tay phải, (tay phải cầm 2 cái), nhân tiện lượm luôn cái nĩa. Cách này nhanh hơn
3. Cách 2.2: Đưa nĩa qua tay trái, (tay trái cầm 2 cái), luôn tiện cầm lại cái muỗng. Giống như cách 2.1
4. Cách 3: Vất cả 2 xuống bàn rồi lượm lên cái đúng. Nhanh hơn 1 tẹo.
5. Cách 4: Tung hứng: Hai tay cùng lúc quăng qua nhau và cùng chụp cái còn lại. Cách này nhanh nhất. Và không cần trung gian. Nhưng về logic không thể thực hiện.
 
Lần chỉnh sửa cuối:
Upvote 0
Thử đoạn code này xem sao:

Mã:
    If arr(i, 2) <= arr(i, 1) Then
        kq(i, 1) = arr(i, 1)
        kq(i, 2) = arr(i, 2)
    Else
        kq(i, 1) = arr(i, 2)
        kq(i, 2) = arr(i, 1)
    End If
Đây cũng là cách dùng qua trung gian là biến mảng. Thử dùng chỉ 1 mảng thôi xem?
 
Lần chỉnh sửa cuối:
Upvote 0
Đây cũng là cách dùng qua trung gian là biến mảng. Thử dùng chỉ 1 mảng thôi xem?
Code này em dùng 1 mảng duy nhất. Mong thầy và các anh chị góp ý!
Mã:
Public Sub doi()
Dim i As Long, arr()
arr = Sheet1.Range("I14:J" & Sheet1.Range("J65500").End(xlUp).Row)
ReDim kq(1 To UBound(arr, 1), 1 To 2)
For i = 1 To UBound(arr, 1)
    If arr(i, 2) > arr(i, 1) Then
        arr(i, 1) = arr(i, 1) & arr(i, 2)
        arr(i, 2) = Left(arr(i, 1), Len(arr(i, 1)) - Len(arr(i, 2)))
        arr(i, 1) = Right(arr(i, 1), Len(arr(i, 1)) - Len(arr(i, 2)))
    End If
Next i
        Sheet1.Range("I14").Resize(UBound(arr, 1), 2).Value = arr
End Sub
 
Upvote 0
Code này em dùng 1 mảng duy nhất. Mong thầy và các anh chị góp ý!
Mã:
Public Sub doi()
Dim i As Long, arr()
arr = Sheet1.Range("I14:J" & Sheet1.Range("J65500").End(xlUp).Row)
ReDim kq(1 To UBound(arr, 1), 1 To 2)
For i = 1 To UBound(arr, 1)
    If arr(i, 2) > arr(i, 1) Then
        arr(i, 1) = arr(i, 1) & arr(i, 2)
        arr(i, 2) = Left(arr(i, 1), Len(arr(i, 1)) - Len(arr(i, 2)))
        arr(i, 1) = Right(arr(i, 1), Len(arr(i, 1)) - Len(arr(i, 2)))
    End If
Next i
        Sheet1.Range("I14").Resize(UBound(arr, 1), 2).Value = arr
End Sub
Code sao lại có dòng Redim kq(), hay là Redim arr()?
Đoạn If ... End chỉ cần
If arr(i,2)>arr(i,1) then
tmp=arr(i,1)
arr(i,1)=arr(i,2)
arr(i,2)=tmp
endif
Còn nếu bạn không muốn dùng biến tạm thì có thể dùng đoạn code sau nhưng tốc độ chậm hơn
If arr(i,2)>arr(i,1) then
arr(i,1)=arr(i,1)+arr(i,2)
arr(i,2)=arr(i,1)-arr(i,2)
arr(i,1)=arr(i,1)-arr(i,2)
End if
 
Upvote 0
Code này em dùng 1 mảng duy nhất. Mong thầy và các anh chị góp ý!

Chuot ơi là Chuot!!!
Thày Ptm0412 đã nêu 4 cách và có xếp loại:
-Loai 4: Tối thượng sách (Cách này dành cho đệ tử Ngô Bảo Châu nha vì Ptm0412 đã cảnh báo rồi)
-Loại 3:Thượng sách: Khai một mảng Tmp cùng kích cỡ với mảng nguồn rồi nhặt cái đúng sang mảng Tmp. Cuối cùng gán mảng nguồn bằng mảng Tmp.
-Loại 2: Trung sách ( Nhưng đây mới chính là hạ sách vì 1 tay cầm cả thìa đường và thìa mỡ. Việc không để mỡ dính đường còn khó hơn là để tạm xuống bàn)

Vậy là Chuot bị dính Hạ sách rồi, động tác ghép dữ liệu rồi tách dữ liệu chắc chắn chậm hơn việc gửi dữ liệu
 
Lần chỉnh sửa cuối:
Upvote 0
Code sao lại có dòng Redim kq(), hay là Redim arr()?
Đoạn If ... End chỉ cần
If arr(i,2)>arr(i,1) then
tmp=arr(i,1)
arr(i,1)=arr(i,2)
arr(i,2)=tmp
endif
Còn nếu bạn không muốn dùng biến tạm thì có thể dùng đoạn code sau nhưng tốc độ chậm hơn
If arr(i,2)>arr(i,1) then
arr(i,1)=arr(i,1)+arr(i,2)
arr(i,2)=arr(i,1)-arr(i,2)
arr(i,1)=arr(i,1)-arr(i,2)
End if
Do mình sửa từ đoạn code trước nên thừa!
 
Upvote 0
Chuot ơi là Chuot!!!
Thày Ptm0412 đã nêu 4 cách và có xếp loại:
-Loai 4: Tối thượng sách (Cách này dành cho đệ tử Ngô Bảo Châu nha vì Ptm0412 đã cảnh báo rồi)
-Loại 3:Thượng sách: Khai một mảng Tmp cùng kích cỡ với mảng nguồn rồi nhặt cái đúng sang mảng Tmp. Cuối cùng gán mảng nguồn bằng mảng Tmp.
-Loại 2: Trung sách ( Nhưng đây mới chính là hạ sách vì 1 tay cầm cả thìa đường và thìa mỡ. Việc không để mỡ dính đường còn khó hơn là để tạm xuống bàn)

Vậy là Chuot bị dính Hạ sách rồi, động tác ghép dữ liệu rồi tách dữ liệu chắc chắn chậm hơn việc gửi dữ liệu
Nếu dùng thêm 1 mảng nữa thì code trước em đã làm rồi.
Mã:
Public Sub doi()
Dim arr(), kq(), i As Long
arr = Sheet1.Range("I14:J" & Sheet1.Range("J65500").End(xlUp).Row)
ReDim kq(1 To UBound(arr, 1), 1 To 2)


For i = 1 To UBound(arr, 1)
    If arr(i, 2) <= arr(i, 1) Then
        kq(i, 1) = arr(i, 1)
        kq(i, 2) = arr(i, 2)
    Else
        kq(i, 1) = arr(i, 2)
        kq(i, 2) = arr(i, 1)
    End If
Next i
        Sheet1.Range("I14").Resize(UBound(arr, 1), 2).Value = kq
End Sub
Ý của thầy PTM là chỉ dùng 1 mảng thôi nên em làm theo cách sau. Cái này em làm không để ý đến tốc độ mà.
Đây cũng là cách dùng qua trung gian là biến mảng. Thử dùng chỉ 1 mảng thôi xem?
 
Lần chỉnh sửa cuối:
Upvote 0
Code sao lại có dòng Redim kq(), hay là Redim arr()?
Đoạn If ... End chỉ cần
If arr(i,2)>arr(i,1) then
tmp=arr(i,1)
arr(i,1)=arr(i,2)
arr(i,2)=tmp
endif
Còn nếu bạn không muốn dùng biến tạm thì có thể dùng đoạn code sau nhưng tốc độ chậm hơn
If arr(i,2)>arr(i,1) then
arr(i,1)=arr(i,1)+arr(i,2)
arr(i,2)=arr(i,1)-arr(i,2)
arr(i,1)=arr(i,1)-arr(i,2)
End if
Hay quá vậy là em học thêm được 1 phép toán nữa trên mảng.
 
Upvote 0
Tôi đọc đề bài vài lượt, vẫn không thấy chỗ nào bắt buộc phải dùng code VBA.

Nếu là tôi thì tôi dùng hàm MIN, MAX chép vào cột phụ. Sau đó copy/paste values trở lại, và xoá cột phụ.
 
Upvote 0
Tôi đọc đề bài vài lượt, vẫn không thấy chỗ nào bắt buộc phải dùng code VBA.

Nếu là tôi thì tôi dùng hàm MIN, MAX chép vào cột phụ. Sau đó copy/paste values trở lại, và xoá cột phụ.
_____________________________________________
từ hình trên, b là chiều rộng, a là chiều dài
cho i đi từ I14 đến I65000 và j đi từ J14 đến J65000 nếu I > J thì đổi giá trị J sang I và nguợc lại.
Tóm lại là dò từ trên xuống nếu chiều rông nhỏ hơn chiều dài thì đổi giá trị chiều rộng sang chiều dài và ngược lại(nếu bằng nhau thi giữ nguyên hoặc đổi cũng ko sao). làm sao giá trị chiều dài luôn lớn hơn hoặc bằng chiều rộng.
Lưu ý: chỉ đổi giá trị (chứ không đổi Ô hay đổi cột)
...........
Vậy khai báo biến i và j thế nào vậy a!!
 
Upvote 0
Tôi hiểu rằng đó là cách giải của chủ thớt. Không biết rằng đó là điều kiện bắt buộc của đề bài. Xin lỗi vậy.

Quý vị có cái thú khi viết được đoạn code VBA. Tôi thì ngược lại, tìm được cách không phải viết cocde là tôi mừng rơn. Mừng quá cho nên đâm ra chủ quan.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi hiểu rằng đó là cách giải của chủ thớt. Không biết rằng đó là điều kiện bắt buộc của đề bài. Xin lỗi vậy.

Quý vị có cái thú khi viết được đoạn code VBA. Tôi thì ngược lại, tìm được cách không phải viết cocde là tôi mừng rơn. Mừng quá cho nên đâm ra chủ quan.

-Đó là hướng đi, cách giải, cách lựa chọn của chủ thớt ! Mình giống như bạn thôi, tìm được cách giải đơn giản ,dễ hiểu , không phức tạp là tuyệt nhất rồi!
Với mình khi gặp một yêu cầu mình sẽ lựa chọn như sau :
-Nếu tìm được cách giải quyết bằng các phương tiện trong excel thì chẳng dại gì mà phải viết code VBA cho khổ, vừa khổ cho mình, vừa làm khó cho người xung quanh ( vì hầu hết các file ở dạng chia sẻ, và người sử dụng không phải ai cũng biết về VBA)
- nếu công thức mảng , hay công thức dài + phức tạp : nên tạo thêm cột phụ, để cho công thức tường minh và dễ hiểu hơn !
Đó là quan điểm của mình !
___________________________
Chủ thớt gặp vướng mắc về cách viết code, thì mình cũng chỉ tập trung vào vấn đề này , hổng có dám mở rông, nhỡ không đúng ý người ta thì lại phiền chết ^^ ,phải không bạn Nda582 ?
 
Upvote 0
Code này em dùng 1 mảng duy nhất. Mong thầy và các anh chị góp ý!
Mã:
Public Sub doi()
Dim i As Long, arr()
arr = Sheet1.Range("I14:J" & Sheet1.Range("J65500").End(xlUp).Row)
ReDim kq(1 To UBound(arr, 1), 1 To 2)
For i = 1 To UBound(arr, 1)
    If arr(i, 2) > arr(i, 1) Then
        arr(i, 1) = arr(i, 1) & arr(i, 2)
        arr(i, 2) = Left(arr(i, 1), Len(arr(i, 1)) - Len(arr(i, 2)))
        arr(i, 1) = Right(arr(i, 1), Len(arr(i, 1)) - Len(arr(i, 2)))
    End If
Next i
        Sheet1.Range("I14").Resize(UBound(arr, 1), 2).Value = arr
End Sub
Mong thầy ptm góp ý thêm về cách dùng 1 mảng duy nhất ạ.
 
Upvote 0
Mong thầy ptm góp ý thêm về cách dùng 1 mảng duy nhất ạ.
Bài 4 của Hungpecc1 chỉ có 1 mảng đấy thôi. Nhưng Hungpecc1 đang dùng 2 biến trung gian, có thể sửa thành 1 biến trung gian.
Ghi chú:
Hai biến trung gian hungpecc1 đang dùng là biến đơn. Có thể dùng chỉ 1 biến đơn.

Dùng biến đơn sẽ tiết kiệm bộ nhớ và không tốn thời gian truy cập như biến mảng. Và 1 biến đơn sẽ có thể sử dụng nhiều lân.
Đó là cách Hau151978 dùng ở bài 14.
 
Lần chỉnh sửa cuối:
Upvote 0
___________________________
Chủ thớt gặp vướng mắc về cách viết code, thì mình cũng chỉ tập trung vào vấn đề này , hổng có dám mở rông, nhỡ không đúng ý người ta thì lại phiền chết ^^ ,phải không bạn Nda582 ?
Theo e, thì 1 bài giải có nhiều phương pháp, cuối cùng thì cũng ra kết quả....nhưng nhiều khi mở rộng ra 1 ít cũng tốt cho người hỏi và người trả lời (đặc biệt là: e mới tìm hiểu VBA thôi nên biết thêm 1 chút), nếu như ko đúng ý thì e hỏi lại cũng đâu có sao? và các câu trả lời của các a(c) đầu đúng!! giúp e thêm đc 1 vấn đề khác!! hì hì
 
Upvote 0
Nếu dữ liệu so sánh trong bài chỉ là kiểu sô nguyên Long thì code trên không vấn đề .
Tuy nhiên mình cũng chia sẻ thêm :
*khi dùng điều kiện so sánh toán tử A < B phải xét đến 2 trường hợp:
-TH1: A , B là số liệu dạng chuỗi (str)
-TH2: A,B là dữ liệu kiểu số:
ví dụ : tại ô A1 : dữ liệu là '20.426789
tại ô B1 : dữ liệu là '40.426
Lúc này điều kiện if A1 > B1 luôn thỏa mãn tức là A1> B1 vì đây là so sánh chuỗi .
Tùy yêu cầucủa bài toán, mà ta xác định tiêu chí so sánh, vấn đề này luôn luôn phải được cân nhắc , nếu không kết quả bài toán sẽ hoàn toàn đi theo hướng khác !

Chờ hoài chả thấy ai giải quyết cái này. Giải theo cách của tôi vậy.

Mã:
Sub TenGiCungDuoc()
[COLOR=#008000]... ' lập mảng vân vân[/COLOR]
[COLOR=#008000]' vòng lặp duyệt mảng[/COLOR]
For dong = 1 to UBound(Mang)
    XepLai Mang(dong, 1), Mang(dong, 2)
Next dong
[COLOR=#008000]' kết vòng lặp duyệt mảng[/COLOR]
[COLOR=#008000]... ' ghi mảng trở lại sheet[/COLOR]
End Sub

Private Sub XepLai(ByRef v1 As Variant, ByRef v2 As Variant)
' Ensures that the smaller value is at v1 and the larger is at v2
If IsNumeric(v1) And IsNumeric(v2) Then
    If Val(b1) > Val(v2) Then HoanTri v1, v2
Else
    If b1 > v2 Then HoanTri v1, v2
End If
End Sub

Private Sub HoanVi(ByRef a As Variant, ByRef b As Variant)
' Swaps values between a and b
Dim c As Variant
c = a
a = b
b = c
End Sub
 
Upvote 0

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

Back
Top Bottom