Bài tập VBA - Macro

Liên hệ QC
Bài này dùng đệ quy cho đỡ phải viết nhiều. Mình online bằng điện thoại, test sau.
Mã:
Function DecimalToBinary(Byval n&) As String
   If n<2 Then
       DecimalToBinary=CStr(n)
    Else
        DecimalToBinary=DecimalToBinary(Int(n/2)) & (n Mod 2)
   End If
End Function

của tôi thì như vậy
Mã:
Function NhiPhan(n, ByRef Tam As String) As String
        If (n > 0) Then
          NhiPhan = NhiPhan(Int(n / 2), Tam)
          Tam = Tam & n Mod 2
       End If
    NhiPhan = Tam
End Function
các thành viên khác có thể tham gia viết code bằng vòng lặp hoặc đệ quy hoặc thấy thuật toán nào hay mình tham gia viết để học hỏi kinh nghiệm
 
Cách của mình chắc chỉ đệ quy cho vui thôi, dùng vòng lặp hiệu quả hơn nhiều.
Mã:
Function NT(ByVal p&, ByVal q&) As Boolean
    If q < 2 Then
        NT = True
        Exit Function
    End If
    If p Mod q = 0 Then NT = False Else NT = NT(p, q - 2)
End Function
Function KTNT(ByVal p&) As Boolean
    If p < 2 Then
        KTNT = False
    ElseIf p < 4 Then
        KTNT = True
    ElseIf p Mod 2 = 0 Then
        KTNT = False
    Else
        KTNT = NT(p, Int(Sqr(p)))
    End If
End Function
Bài này mình cần sửa lại. Do hàm NT chỉ cần xét các tham số q lẻ nên lệnh cuối của hàm KTNT cần sửa thành
KTNT = NT(p, Int(Sqr(p)) - 1 + (Int(Sqr(p)) Mod 2))
Mã:
Function NT(ByVal p&, ByVal q&) As Boolean
    If q < 2 Then
        NT = True
        Exit Function
    End If
    If p Mod q = 0 Then NT = False Else NT = NT(p, q - 2)
End Function
Function KTNT(ByVal p&) As Boolean
    If p < 2 Then
        KTNT = False
    ElseIf p < 4 Then
        KTNT = True
    ElseIf p Mod 2 = 0 Then
        KTNT = False
    Else
        KTNT = NT(p, Int(Sqr(p)) - 1 + (Int(Sqr(p)) Mod 2))
    End If
End Function
 
Bài tiếp theo dễ hơn bài trước nhiều, các thành viên mới nên tham gia để học hỏi tư duy:
Yêu cầu chuyển 1 số từ hệ thập phân sang hệ nhị phân? (nếu có thể thì làm bằng vòng lặp và đệ quy luôn)
ví dụ N= 15 thì kết quả mong muốn là 1111
ví dụ N= 10 thì kết quả mong muốn là 1010
chúc các bạn ngày mới vui vẻ
Thử code này xem sao!
Mã:
Public Function SoNhiPhan(n) As String
Dim a As Integer, b As Integer, Tmp As String
    Tmp = ""
Do While n >= 1
    a = n Mod 2: b = Int(n / 2)
    Tmp = a & Tmp: n = b
Loop
    SoNhiPhan = Tmp
End Function
 
Thử code này xem sao!
Mã:
Public Function SoNhiPhan(n) As String
Dim a As Integer, b As Integer, Tmp As String
    Tmp = ""
Do While n >= 1
    a = n Mod 2: b = Int(n / 2)
    Tmp = a & Tmp: n = b
Loop
    SoNhiPhan = Tmp
End Function
tôi rút ngắn lại dùm bạn một tí xíu
Mã:
Public Function SoNhiPhan(n) As String
Dim Tmp As String
    Tmp = ""
Do While n > 0
         Tmp = n Mod 2 & Tmp
          n = Int(n / 2)
Loop
    SoNhiPhan = Tmp
End Function
Những bạn trên diễn đàn muốn học VBA mà không chịu tham gia giải các bài tập để rèn luyện tư duy cho sum tụ để các thành viên đưa ra các chủ đề còn hứng thú nghĩ ra nhiều bài tập. Chứ vắng hoe thành viên tham gia thì nản lắm
 
Lần chỉnh sửa cuối:
tôi rút ngắn lại dùm bạn một tí xíu
Mã:
Public Function SoNhiPhan(n) As String
Dim Tmp As String
    Tmp = ""
Do While n > 0
         Tmp = n Mod 2 & Tmp
          n = Int(n / 2)
Loop
    SoNhiPhan = Tmp
End Function
Những bạn trên diễn đàn muốn học VBA mà không chịu tham gia giải các bài tập để rèn luyện tư duy cho sum tụ để các thành viên đưa ra các chủ đề còn hứng thú nghĩ ra nhiều bài tập. Chứ vắng hoe thành viên tham gia thì nản lắm
Chắc tại ngày lễ mà anh Phi.
 
Xin phép ra đề dựa vào bài tập trước của anh Phi
---------------------------------------------------------------------
Đề bài: Chuyển các số nhị phân sang số thập phân.
----------------------------------------------------------------
Đáp án đây:
(
Chỉ xem khi bạn viết xong code)
Mã:
[COLOR=#f0ffff]Public Function ConvertSNPtoSTP(snp) As Integer
Dim i As Long, So As Long
For i = 1 To Len(snp)
    So = So + Val(Mid(snp, i, 1)) * 2 ^ (Len(snp) - i)
Next i
    ConvertSNPtoSTP = So[/COLOR]
[COLOR=#f0f8ff]End Function[/COLOR]
 
Lần chỉnh sửa cuối:
Liên quan đến số nhị phân, tôi thấy các bạn quá chủ quan khi không nghĩ đến trường hợp SỐ ÂM
Có ai biết trong Excel, các con số -1, -2, -3... (hệ thập phân) được biểu diễn sang nhị phân như thế nào không?
Tôi dùng hàm DEC2BIN trên Excel và có kết quả như sau:
- DEC2BIN(-1) cho kết quả 1111111111
- DEC2BIN(-2) cho kết quả 1111111110
- DEC2BIN(-3) cho kết quả 1111111101

và hàm DEC2BIN giới hạn tối đa đến số 511 (công thức =DEC2BIN(512) báo lỗi). Thêm nữa công thức =DEC2BIN(511) cho kết quả 111111111 là 9 con số 1, trong khi DEC2BIN(số âm) cho kết quả 1 chuỗi 10 ký tự
Cảm giác dường như anh Bill dùng con số 1 đầu tiên bên trái để ký hiệu số âm hay sao ấy. Mà nghĩ lại thấy cũng hợp lý: Máy tính nó chỉ biết 0 và 1 chứ làm gì biết dấu - của số âm. Vậy cũng phải có cách chuyển đổi gì đó chứ nhỉ? (quy ước)
 
Lần chỉnh sửa cuối:
Liên quan đến số nhị phân, tôi thấy các bạn quá chủ quan khi không nghĩ đến trường hợp SỐ ÂM
Có ai biết trong Excel, các con số -1, -2, -3... (hệ thập phân) được biểu diễn sang nhị phân như thế nào không?
Cái này liên quan tới bù 1 bù 2 với lại trên diễn đàn cũng ít người biết đến biểu diễn số nhị phân nhiều, nên các bài tập về nhị phân thì mình hạn chế chỉ biểu diễn số dương thôi anh.

Ví dụ 5 = 00000101
bù 1 của -5 ( bù 1 là đảo các số ngược lại với sô dương)
-5= 11111010
Bù 2 ( Bù 2 là đảo các số ngược lại với số dương sau đó +1
-5 = 11111011
 
Lần chỉnh sửa cuối:
Trong toán học bít dấu người ta không thể hiện( vì nó ngầm hiểu bít đầu tiên là số 1 vì là số âm) trong biểu diễn anh
 
mà nói tới nhị phân là nói tới chuyện dài tập. Cái này nếu anh muốn nghiên cứu thì tìm sách cấu trúc máy tính thì sẽ rõ hơn, sách đó nói rõ ràng các phép tính cộng trừ nhân chia số mũ ... trong hệ nhị phân(thực sự trong hệ nhị phân chỉ có phép cộng mà thôi những cái khác là biến thể của phép cộng)
 
Tôi xin có ý kiến riêng 1 chút. Theo tôi bắt đầu từ các bài tập mới bây giờ nên đánh số thứ tự của bài tập để các thành viên dễ tham gia giải mà người đưa bài tập cũng dễ quản lí. Nội dung bài tập nên đưa vào tag code cho dễ nhìn, dễ đọc. Chủ để khá dài rồi. Bài tập và các nội dung thì cứ đan xen nhau.
 
Trong toán học bít dấu người ta không thể hiện( vì nó ngầm hiểu bít đầu tiên là số 1 vì là số âm) trong biểu diễn anh
VBA lưu số âm theo phương pháp bù 2. Chỉ có kiểu Interger (16 bit) và Long (32 bit) mới có số âm còn kiểu Byte (8 bit) không có.
Bit dấu vẫn tồn tại. Đối với số interger số dương lớn nhất là 0111 1111 1111 1111 =2^15-1 = 32767. Số âm nhỏ nhất là a=1000 0000 0000 0000, a-1=0111 1111 1111 1111, sau khi đảo các bit được 1000 0000 0000 0000 = 2^15 = 32768 nên số âm nhỏ nhất là -32768.
Tương tự số Long từ -2^31 đến 2^31-1.
 
Đối với thành viên mới học VBA như mình thì chỉ quan tâm đến cái gì đó cụ thể, ứng dụng được cho công việc. Chứ mấy dạng thuật toán cao cấp như đệ quy, nhị phân hay thập phân gì gì đó thì mình chẳng dám đụng vào làm gì chỉ mất sức. Cứ thử kéo dài dạng bài tập thế này thì cứ chờ xem coi có thành viên mới nào dám tham gia hay không nhé.
Đã là bài tập thì phải mang tính vừa sức, hoặc chỉ ráng thêm tí là tới. Đằng này xa tít mù khơi thì ráng sao nổi. Thử hỏi trên GPE được mấy người có học bài bản về lập trình. Dân đi làm thì cứ là lọc dữ liệu, thống kê dữ liệu....
Đối với những người khá hơn chút mà có tí máu me với code thì mới thức đêm thức hôm để luyện. Mà luyện cũng chỉ cho vui chứ sau 1 thời gian không xài thì cũng trả lại cho bác Bill sạch.

Ngắn gọn lại là: muốn có nhiều thành viên mới tham gia vào cho hào hứng chủ đề thì chúng ta nên xem lại các bài tập đã, đang và sẽ post lên diễn đàn. Còn những dạng kiến thức trung, cao cấp thì nên mở riêng chủ đề riêng. Chẳng hạn nói về thuật toán đệ quy, theo mình thì đó là kiến thức lập trình cao cấp và chắc ít người am tường.

Vài lời chia sẻ, nếu có gì mạo phạm mong mọi người lượng thứ và không ném đá túi bụi.
 
Anh Hải nói chí lý, muốn khởi động topic này cho sum tụ thì cần lắm những vấn đề thực tế mà các thành viên gạo cội đã gặp phải để cho các thành viên mới học hỏi thêm.
 
Lập trình bằng VB thiên về lập trình ứng dụng nhiều hơn, vấn đề thuật toán thường là thứ yếu. Hồi học THPT về tin học có lẽ học thuật toán là thứ mình ghét nhất. Sau này khi VB ra đời khiến cho "ai cũng có thể trở thành lập trình viên", mọi thứ đã được VB làm hết.
Trở lại bài #86 của bạn chuot0106, code này đúng, ngắn gọn nhưng tốc độ chậm do mỗi lần tính 2, 2^2, 2^3... các số này đều tính lại từ đầu dẫn đến thừa nhiều phép nhân. Mình cải tiến code đó như sau:
Mã:
Function Binary2Decimal(ByVal b) As Long
    Dim tmp, s, i&, n&
    n = Len(b)
    tmp = 1
    For i = 1 To n
       s = Mid(b, n - i + 1, 1)
       Binary2Decimal = Binary2Decimal + IIf(s = 0, 0, tmp)
       tmp = tmp * 2
    Next
End Function
Trong code này, biến tmp sẽ lưu các giá trị lũy thừa của 2, biến n lưu giá trị LEN(b) mà không dùng trực tiếp trong vòng lặp để tránh LEN(b) phải tính lại nhiều lần.
 
Lần chỉnh sửa cuối:
Đối với thành viên mới học VBA như mình thì chỉ quan tâm đến cái gì đó cụ thể, ứng dụng được cho công việc. Chứ mấy dạng thuật toán cao cấp như đệ quy, nhị phân hay thập phân gì gì đó thì mình chẳng dám đụng vào làm gì chỉ mất sức. Cứ thử kéo dài dạng bài tập thế này thì cứ chờ xem coi có thành viên mới nào dám tham gia hay không nhé.
Đã là bài tập thì phải mang tính vừa sức, hoặc chỉ ráng thêm tí là tới. Đằng này xa tít mù khơi thì ráng sao nổi. Thử hỏi trên GPE được mấy người có học bài bản về lập trình. Dân đi làm thì cứ là lọc dữ liệu, thống kê dữ liệu....
Đối với những người khá hơn chút mà có tí máu me với code thì mới thức đêm thức hôm để luyện. Mà luyện cũng chỉ cho vui chứ sau 1 thời gian không xài thì cũng trả lại cho bác Bill sạch.

Ngắn gọn lại là: muốn có nhiều thành viên mới tham gia vào cho hào hứng chủ đề thì chúng ta nên xem lại các bài tập đã, đang và sẽ post lên diễn đàn. Còn những dạng kiến thức trung, cao cấp thì nên mở riêng chủ đề riêng. Chẳng hạn nói về thuật toán đệ quy, theo mình thì đó là kiến thức lập trình cao cấp và chắc ít người am tường.

Vài lời chia sẻ, nếu có gì mạo phạm mong mọi người lượng thứ và không ném đá túi bụi.

Đồng ý!
Và thêm nữa: Dù là bài tập đi chăng thì cũng phải có ứng dụng thực tế và cụ thể
(nếu không thì học rồi áp dụng vào đâu?)
 
Lần chỉnh sửa cuối:
Lập trình bằng VB thiên về lập trình ứng dụng nhiều hơn, vấn đề thuật toán thường là thứ yếu. Hồi học THPT về tin học có lẽ học thuật toán là thứ mình ghét nhất. Sau này khi VB ra đời khiến cho "ai cũng có thể trở thành lập trình viên", mọi thứ đã được VB làm hết.
Trở lại bài #86 của bạn chuot0106, code này đúng, ngắn gọn nhưng tốc độ chậm do mỗi lần tính 2, 2^2, 2^3... các số này đều tính lại từ đầu dẫn đến thừa nhiều phép nhân. Mình cải tiến code đó như sau:
Mã:
Function Binary2Decimal(ByVal b) As Long
    Dim tmp, s, i&, n&
    n = Len(b)
    tmp = 1
    For i = 1 To n
       s = Mid(b, n - i + 1, 1)
       Binary2Decimal = Binary2Decimal + IIf(s = 0, 0, tmp)
       tmp = tmp * 2
    Next
End Function
Trong code này, biến tmp sẽ lưu các giá trị lũy thừa của 2, biến n lưu giá trị LEN(b) mà không dùng trực tiếp trong vòng lặp để tránh LEN(b) phải tính lại nhiều lần.
Đúng là lập trình chuyên nghiệp nên tính đến cả vấn đề thời gian. Tại em viết code xong thử các trường hợp thấy kết quả đúng là mừng lẳm rồi. Mà tại chuyển mấy con số nhị phân sang thập phân nên thời gian ít em mình không để ý đến vấn đề thời gian. Chứ nếu phải làm việc với dữ liệu lớn thì vấn đề tối ưu code là rất quan trọng.
 
Đúng là lập trình chuyên nghiệp nên tính đến cả vấn đề thời gian.
cái này không đúng lắm à nha, lập trình chuyên nghiệp phải tính đến việc tối ưu. Thời gian nhanh chưa phải là tối ưu nha bạn.
ví dụ đơn giản có 1 công việc cần làm
Cách 1 : chi phí bỏ ra 1 tỷ đồng cho thời gian 2 ngày
Cách 2 : chi phí bỏ ra 10 triệu đồng cho thời gian 1 tháng
bạn suy nghĩ như thế nào về 2 cách làm này
 
[thongbao]Và thêm nữa: Dù là bài tập đi chăng thì cũng phải có ứng dụng thực tế và cụ thể
(nếu không thì học rồi áp dụng vào đâu?)[/thongbao]

/-)ây vẫn là vấn nạn của ngành GD Việt nam, mà ở những Trung tâm TH cũng khó mà tránh khỏi;

Người ta chỉ vin vào câu: Ở trường người ta chỉ chuyển giao những cái cơ bản; Còn chuyện áp dụng ngoài đời thì anh tự bơi!

Sau khi đã có bùa hộ mệnh, người ta đẩy những cái cơ bản đó đến vùng sâu vùng xa của lĩnh vực đó!

Còn các chàng sinh viên thì không biết không khí thở gồm 3 chất gì là chủ yếu nhất!
Hay sông Mê công chảy qua nước Malaixia.
 
Web KT
Back
Top Bottom