Mơ hồ lắm. Có chuyển được hêt các thể loại về một kiểu a) cho mình thì chuyển.@Euler a) và b) nếu gần nhau thì tương đương (anh em); i) và ii) cũng vậy nhưng "a)" rồi đến "i)" thì "a)" là cha của "i)" và ngược lại.
Mơ hồ lắm. Có chuyển được hêt các thể loại về một kiểu a) cho mình thì chuyển.@Euler a) và b) nếu gần nhau thì tương đương (anh em); i) và ii) cũng vậy nhưng "a)" rồi đến "i)" thì "a)" là cha của "i)" và ngược lại.
Để bài toán được đơn giản hơn, tôi chỉ nhờ giải quyết tình huống câu 1 người dùng đánh thủ công, câu 2 họ dùng list. Các lỗi đánh máy tôi sẽ tự fix. Dấu hiệu mỗi item là trước mặt có tab hoặc xuống dòng (có 2 hay 3 trường hợp trong thực tế tôi quên ghi lại) hoặc xuống dòng cộng cách. Có một loại nhiều item trên 1 dòng, 1 loại mỗi item có một dòng. Trong các item có thể có nhiều đoạn.Nếu theo tài liệu trong topic này thì nó đang có quy luật.
Bạn cần đăng nhập để thấy hình ảnh
Vậy phiền bên phía ra yêu cầu, đưa ra file demo cho các tình huống mà quý vị nêu người ta gõ dấu cách thò thụt như nào, để anh em có cơ sở phán đoán cho được chính xác.
Option Explicit
Const c1 As String = ")"
Const c2 As String = "."
Const c3 As String = "\begin"
Const c4 As String = "\end"
Const c5 As String = "%========>tuhocvba.net>=========%"
Const c6 As String = "tuhocvba.net"
Function CheckLvl(s As String, s1 As String) As Long
Dim n&, k&, i&
Static Dic As Dictionary
If Dic Is Nothing Then
Set Dic = New Dictionary
Dic.CompareMode = TextCompare
Dic.Add "a", 3
Dic.Add "b", 3
Dic.Add "c", 3
Dic.Add "d", 3
Dic.Add ChrW(273), 3
Dic.Add "e", 3
Dic.Add "f", 3
Dic.Add "g", 3
Dic.Add "h", 3
Dic.Add "i", 4
Dic.Add "ii", 4
Dic.Add "iiii", 4
Dic.Add "iv", 4
Dic.Add "v", 4
Dic.Add "vi", 4
Dic.Add "vii", 4
Dic.Add "viii", 4
Dic.Add "ix", 4
Dic.Add "x", 4
End If
Do While Left(s, Len(c6)) = c6
s = Right(s, Len(s) - Len(c6))
Loop
s = Application.WorksheetFunction.Trim(Application.WorksheetFunction.Clean(s))
If InStr(s, "Câu h" & ChrW(787) & "i ") = 1 Then
If IsNumeric(Mid(s, 9, 1)) Then CheckLvl = 1 Else CheckLvl = 0
ElseIf InStr(s, "Câu ") = 1 Then
If IsNumeric(Mid(s, 5, 1)) Then CheckLvl = 1 Else CheckLvl = 0
Else
i = InStr(s, c1)
k = InStr(s, c2)
If (k > 0 And i > k) Or (i = 0) Then i = k
If i > 0 Then
s1 = Left(s, i - 1)
If IsNumeric(s1) Then
CheckLvl = 2
ElseIf Dic.Exists(s1) Then
CheckLvl = Dic.Item(s1)
End If
Else
CheckLvl = 0
End If
End If
End Function
Sub Convert()
Dim r As Range, arr(), kq(), arrS
Dim n&, i&, j&, k&, LastLvl&
Dim LastString$, s$, s1$
Set r = Range("A1").CurrentRegion
arr = r
n = UBound(arr, 1)
ReDim kq(1 To n * 2, 1 To UBound(arr, 2))
arrS = Array("{cau}", "{enumerate}", "\item ")
LastLvl = -1
For i = 1 To n
s = arr(i, 1)
k = CheckLvl(s, s1)
If k = 1 Then
If j > 0 Then
kq(j + 1, 1) = c4 & arrS(0)
kq(j + 2, 1) = c5
j = j + 2
End If
j = j + 1
kq(j, 1) = c3 & arrS(0)
LastLvl = k
ElseIf k > 1 Then
If k = LastLvl Then
j = j + 1
kq(j, 1) = arrS(2) & Right(s, Len(s) - Len(s1) - 1)
ElseIf k > LastLvl Then
kq(j + 1, 1) = c3 & arrS(1)
kq(j + 2, 1) = arrS(2) & Right(s, Len(s) - Len(s1) - 1)
j = j + 2
Else
kq(j + 1, 1) = c4 & arrS(1)
kq(j + 2, 1) = arrS(2) & Right(s, Len(s) - Len(s1) - 1)
j = j + 2
End If
LastLvl = k
Else
j = j + 1
kq(j, 1) = arr(i, 1)
End If
Next
j = j + 1
kq(j, 1) = c4 & arrS(0)
Range("M1").Resize(j, UBound(arr, 2)).Value = kq
End Sub
1- Bạn cho xin file demo đánh thủ công như thế nào.Để bài toán được đơn giản hơn, tôi chỉ nhờ giải quyết tình huống câu 1 người dùng đánh thủ công
Đã có file mẫu rồi bạn. Link đầu tiên ah.1- Bạn cho xin file demo đánh thủ công như thế nào.
Những người ở đây không hiểu chuyên môn của bạn, vì vậy trình bày dễ hiểu để ngay cả những người không có chuyên môn hiểu bạn muốn gì, code cho chính xác là điều quan trọng.
Chẳng hạn dựa vào danh sách bạn đưa ra thì @NhanSu có lẽ đang code theo hướng a) , b) , c) mặc định là cha của i) ii)
trong khi đó trên word thì đây là hai kiểu list khác nhau và bình đẳng. i) cũng có thể là cha của a). Còn tùy thuộc vào cách gõ của người dùng. Nhưng tôi nghĩ chúng ta có thể thống nhất với nhau rằng, cái nào thò ra ngoài thì là cha của đứa thụt vào trong.
2-Tôi nghĩ nhận thức của tôi là đúng, nếu sai hãy phản hồi lại.
3-Phải xác định được dấu hiệu của một item. Từ đầu topic tới giờ nói là (tôi tạm không nói tới phía trước là tab hay dấu xuống dòng nhé): 1/, 1-, 1. hay a/, a-, a., hay a)
Ngoài ra tôi đang có băn khoăn rằng: Liệu người ta còn sử dụng:
1.
1.1
1.1.1 hay không?
Phải làm rõ toàn bộ các điều kiện trước khi code để tránh việc code trở thành lãng phí.
Nếu như bạn cũng có thể chuẩn hóa input đầu vào luôn, item chỉ có môt dạng cấu trúc như là a) thì người code sẽ nhanh chóng đi vào code chính. Nếu như bạn không làm được chuẩn hóa này, tôi đề xuất: ở mỗi dạng item lấy ra 20 bạn. Không biết bạn gõ đề như thế nào, chứ một câu hỏi mà có tới 20 ý đã là kinh lắm rồi đấy.
Khi đó ta đưa các dạng này vào bộ dữ liệu nhận dạng item:
1) ~ 20)
a) ~ t)
i) ~ xx)
Có thể thay dấu ) thành các dấu - hay /.
Vậy bạn có đồng ý đề xuất này hay không?
Tôi tán thành ý kiến với bác Euler coi mức độ thò thụt làm cơ sở xác định cha-con.
File mẫu của bạn không có trường hợp ngoại lệ nào hết. Tất cả đều sử dụng list. Như vậy nếu code mà đưa cái file mẫu ra output như bạn muốn là được? Sau này nếu phản biện, các file phải tuân thủ theo cấu trúc như file mẫu bạn đưa ra có đúng không?Đã có file mẫu rồi bạn. Link đầu tiên ah.
Mình chỉ hy vọng xử lý được như file mẫu. Các trường hợp phân cấp tôi tự xử lý được.
Chính xác đó là khó khăn của tôi. [a-z,0-9]{1,2}) là trước là xuống dòng hoặc tab là item.Trong file mẫu vẫn có những chỗ chưa dùng list.
Câu 1:
Bạn cần đăng nhập để thấy đính kèm
Xin hỏi tác giả @mathvn là bên đưa yêu cầu, tại sao đây lại là một item.
Giả sử như chỗ này là ă) phía trước có dấu tab.
Hoặc: căn) phía trước có dấu tab.
Thì có coi đó là một item hay không?
Hoặc a1) phía trước có dấu tab, thì có coi đó là một item hay không?
Bạn xem không kĩ rồi. Trong đó có ngoại lệ, có gõ sai, các list không theo qui luật. Bạn xem lại đúng thế không.File mẫu của bạn không có trường hợp ngoại lệ nào hết. Tất cả đều sử dụng list. Như vậy nếu code mà đưa cái file mẫu ra output như bạn muốn là được? Sau này nếu phản biện, các file phải tuân thủ theo cấu trúc như file mẫu bạn đưa ra có đúng không?
Có nghĩa là tôi không chấp nhân việc không sử dụng list mà sử dụng dấu tab hay khoảng trắng để thò thụt đầu dòng nữa, hiểu như vậy có đúng không?
Nó là item vì nó là một ý hỏi của câu.Trong file mẫu vẫn có những chỗ chưa dùng list.
Câu 1:
Bạn cần đăng nhập để thấy đính kèm
Xin hỏi tác giả @mathvn là bên đưa yêu cầu, tại sao đây lại là một item.
Giả sử như chỗ này là ă) phía trước có dấu tab.
Hoặc: căn) phía trước có dấu tab.
Thì có coi đó là một item hay không?
Hoặc a1) phía trước có dấu tab, thì có coi đó là một item hay không?
Máy tính không hiểu thế nào là một ý của câu hỏi.Nó là item vì nó là một ý hỏi của câu.
Tôi viết code như thế này đưa cho bạn, rồi bạn tự sửa lại có được không?Nó là item vì nó là một ý hỏi của câu.
if a = ycuacauhoi then
Các item được xác định bởi 1 trong các trường hợp sau:Máy tính không hiểu thế nào là một ý của câu hỏi.
Nó phải có logic rõ ràng.
Ví dụ: tab + số + )
Hoặc tab + chữ + ) thì phải quy định chữ là chữ nào. Bao nhiêu chữ.
Chứ VBA biết cái gì là ý của câu hỏi, khái niệm ý của câu hỏi là một khái niệm mơ hồ, máy tính không hiểu được.
#include<stdio.h>
#include<string.h>
#include "stdlib.h"
#include<conio.h>
void main()
{
int a[20], len, i = 0, j, k;
char roman[20];
printf("Nhap day chu so La Ma(Note: chi su dung I,V,X,L,C,D,M): ");
gets(roman);
len = strlen(roman);
for(i = 0; i < len; i++)
{
if(roman[i] == 'I')
a[i] = 1;
else if(roman[i] == 'V')
a[i] = 5;
else if(roman[i] == 'X')
a[i] = 10;
else if(roman[i] == 'L')
a[i] = 50;
else if(roman[i] == 'C')
a[i] = 100;
else if(roman[i] == 'D')
a[i] = 500;
else if(roman[i] == 'M')
a[i] = 1000;
else
{
printf("\nXin nhap lai day so la ma");
getch();
exit(1);
}
}
k = a[len-1];
for(i = len-1; i > 0; i--)
{
if(a[i] > a[i-1])
k = k - a[i-1];
else if(a[i] == a[i-1] || a[i] < a[i-1])
k = k + a[i-1];
}
printf("\nGia tri thap phan tuong ung la: %d ", k);
getch();
}
Sub test2()
Dim s As String
s = "viii"
MsgBox Arabic(s)
End Sub
Function Arabic(Roman)
Dim Arabicvalues() As Integer, convertedvalue As Long, currentchar As String * 1
Dim i As Integer, message As String, numchars As Integer
Roman = LTrim(RTrim(Roman))
numchars = Len(Roman)
If numchars = 0 Then 'if arg is null, we're outta here
Arabic = ""
Exit Function
End If
ReDim Arabicvalues(numchars)
For i = 1 To numchars
currentchar = Mid(Roman, i, 1)
Select Case UCase(currentchar)
Case "M": Arabicvalues(i) = 1000
Case "D": Arabicvalues(i) = 500
Case "C": Arabicvalues(i) = 100
Case "L": Arabicvalues(i) = 50
Case "X": Arabicvalues(i) = 10
Case "V": Arabicvalues(i) = 5
Case "I": Arabicvalues(i) = 1
Case Else
Arabic = "Sorry, " & Roman & " is not a valid Roman numeral! "
Exit Function
End Select
Next i
For i = 1 To numchars - 1
If Arabicvalues(i) < Arabicvalues(i + 1) Then
Arabicvalues(i) = Arabicvalues(i) * -1
End If
Next i
For i = 1 To numchars
Arabic = Arabic + Arabicvalues(i)
Next i
End Function
Có vẻ như arabic chỉ có từ phiên bản Excel 2013, 2016,...Số La Mã thì MS đã có công thức rồi, chỉ việc áp dụng. Mọi người test chuỗi làm gì cho khổ vì dù sao cũng chỉ là liệt kê các trường hợp thôi.
Chú ý nên dùng application.roman thay vì worksheetfunction để bẫy lỗi.Mã:application.arabic(txt)