Truy xuất comments trong Word sang Excel

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

KhoiSMC

Thành viên thường trực
Tham gia
19/6/09
Bài viết
248
Được thích
32
Chào các bạn,

Tại box "phần mềm xử lý văn bản và chế bản điện tử": http://www.giaiphapexcel.com/forum/showthread.php?90223-Xuất-comments-trong-word-đến-excel

Mình có câu hỏi sau trong box "phần mềm xử lý văn bản và chế bản điện tử" nhưng chưa có lởi giải, nay nhờ các bạn trong box này giúp đỡ:
Xuất comments trong word đến excel

Kính gửi các bạn GPE,

Mình hay đọc tài liệu trong Microsoft Word và hay tạo các comments trong file word. Hiện nay có phát sinh muốn copy toàn bộ comment trong file word sang excel.

Tuy nhiên mình mới chỉ xuất được các comments sang word với code VBA như sau:
(xem file đính kèm: Schedule visit 10 to 18 March 2014 lgk.doc)

Code:

Sub ExportComments() Dim s As String
Dim cmt As Word.Comment
Dim doc As Word.Document

For Each cmt In ActiveDocument.Comments
s = s & "Tên file: " & cmt.Parent & "; Ghi chú so: " & cmt.Initial & cmt.Index & "; Noi dung: " & cmt.Scope & cmt.Range.Text & vbCr
Next

Set doc = Documents.Add
doc.Range.Text = s

End Sub

Và có kết quả như sau:

Tên file: Schedule visit 10 to 18 March 2014 lgk.doc; Ghi chú so: KLG1; Noi dung: Dominique Chiesura
Title-Hành động bởi: data KLG1
Title-Thời gian thực hiện: data KLG1
Title-Sử dụng cho công việc: data KLG1
Tên file: Schedule visit 10 to 18 March 2014 lgk.doc; Ghi chú so: KLG2; Noi dung: Singapore
Title-Hành động bởi: data KLG2
Title-Thời gian thực hiện: data KLG2
Title-Sử dụng cho công việc: data KLG2
Title-Kinh nghiệm: data KLG2

Mong muốn xuất sang excel thành dạng bảng như sau: (file đính kèm: Book2.xlsx)


Mong các bạn giúp đỡ.

Khoi​

Khoi
 

File đính kèm

Các bạn ơi liệu có giải pháp nào không a?

Khoi
 
Các bạn ơi liệu có giải pháp nào không a?

Khoi
Trước mắt chữa cháy bằng code này đi nhen, copy code vào trong cửa sổ VBA của word nhen bạn

[GPECODE=vb]
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, data
Set xlExcel = CreateObject("Excel.Application")
xlExcel.Visible = True
Set xlWB = xlExcel.Workbooks.Add
With xlWB.Worksheets(1)
i = 0
For Each cmt In ActiveDocument.Comments
i = i + 1
.Cells(i, 1).Value = cmt.Parent
.Cells(i, 2).Value = cmt.Initial & cmt.Index
.Cells(i, 3).Value = cmt.Scope
data = Split(cmt.Range.Text, ":")
For k = 1 To UBound(data)
.Cells(i, 3 + k) = Left(data(k), 11)
Next

Next
End With
Set xlWB = Nothing
Set xlExcel = Nothing
End Sub


[/GPECODE]
 
Cám ơn nmhung49,

Code của bạn đúng đã giải quyết được vấn đề mình đưa ra nhưng có vẻ yêu cầu của mình hơi phức tạp ở phần nội dung trong comments trong word nên mình muốn làm rõ lại ý của mình cho đơn giản hơn nhằm code sẽ chạy đúng cho mọi trường hợp comments bên word, cụ thể như sau:

Mã:
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, data
Set xlExcel = CreateObject("Excel.Application")
xlExcel.Visible = True
Set xlWB = xlExcel.Workbooks.Add
With xlWB.Worksheets(1)
    i = 0
    For Each cmt In ActiveDocument.Comments
        i = i + 1
        .Cells(i, 1).Value = cmt.Parent [COLOR=#0000cd][B]'<-- OK, rõ ràng[/B][/COLOR]
        .Cells(i, 2).Value = cmt.Initial & cmt.Index [COLOR=#0000cd][B]'<-- OK, rõ ràng[/B][/COLOR]
        .Cells(i, 3).Value = cmt.Scope [COLOR=#0000cd][B]'<-- OK, rõ ràng[/B][/COLOR]
       [COLOR=#b22222] data = Split(cmt.Range.Text, ":") [/COLOR][COLOR=#ff0000][B]'<-- dòng code số 16,17,18,19 có thể thay bằng mô tả dưới đây[/B][/COLOR][COLOR=#b22222]
        For k = 1 To UBound(data)
          .Cells(i, 3 + k) = Left(data(k), 11)
        Next[/COLOR]
        
    Next
End With
Set xlWB = Nothing
Set xlExcel = Nothing
End Sub

Tại dòng code số 16 đến 19 mục đích muốn tách phần tiêu đề và nội dung của nó:
Định nghĩa khi viết comments trong word như sau: [Ti] tên tiêu đề [Ti] [data] nội dung của tiêu đề [data]

Khi đưa sang excel thì cứ dòng text bên trong [Ti] trong một cột và trong [data] để vào một cột.

Có một mong muốn nhỏ nữa là bạn có thể thêm một cột trong excel mô tả số trang của word mà comments xuất hiện. Cụ thể mình sửa file word (xin bạn download file word đính kèm).

và mong muốn xuất sang excel như sau: (file kết quả excel đính kèm)
Untitled.jpg

Cám ơn bạn nhiều a.
Khoi
 

File đính kèm

Mình cũng muốn giúp đỡ bạn lắm như mình không có khả năng để tách [Ti] với [Data] mình nghĩ có thể dùng VBscript.Regexp để làm việc này mà nghĩ chưa ra nên không thể giúp bạn được
 
Thanks bạn, như vậy cần phải định nghĩa [Ti] và [Data] bằng cách nào đó đơn giản hơn là tuỳ bạn để có thể tách thành hai cột cũng được bạn ạ.

Cám ơn nmhung49 đã quan tâm giúp đỡ.
khoi
 
Nhờ các cao thủ khác ra tay giúp đỡ với ạ.

Khoi
 
Nhờ các cao thủ khác ra tay giúp đỡ với ạ.

Khoi

Bạn nmhung49 đã gợi ý thì ta dùng món VBscript.Regexp nhỉ?

Bạn thay code cũ bằng code sau:

Mã:
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, re As Object, colMatches As Object
    Set xlExcel = CreateObject("Excel.Application")
    xlExcel.Visible = True
    Set xlWB = xlExcel.Workbooks.Add
    Set re = CreateObject("VBScript.RegExp")
    re.Global = True
    re.Pattern = "(\[data\]).*?\1"
    i = 1
    With xlWB.Worksheets(1)
        For Each cmt In ActiveDocument.Comments
            i = i + 1
            .Cells(i, 1).Value = cmt.Parent
            .Cells(i, 2).Value = cmt.Initial & cmt.Index
            .Cells(i, 3).Value = cmt.Scope
            If re.test(cmt.Range.text) Then
                Set colMatches = re.Execute(cmt.Range.text)
                For k = 1 To colMatches.Count
                    .Cells(i, 3 + k) = Trim(Replace(colMatches.Item(k - 1).Value, "[data]", ""))
                Next
            End If
        Next
    End With
    Set colMatches = Nothing
    Set re = Nothing
    Set xlWB = Nothing
    Set xlExcel = Nothing
End Sub

Nhớ là phải [data], tức không có dấu cách.
 
Bạn nmhung49 đã gợi ý thì ta dùng món VBscript.Regexp nhỉ?

Bạn thay code cũ bằng code sau:

Mã:
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, re As Object, colMatches As Object
    Set xlExcel = CreateObject("Excel.Application")
    xlExcel.Visible = True
    Set xlWB = xlExcel.Workbooks.Add
    Set re = CreateObject("VBScript.RegExp")
    re.Global = True
    re.Pattern = "(\[data\]).*?\1"
    i = 1
    With xlWB.Worksheets(1)
        For Each cmt In ActiveDocument.Comments
            i = i + 1
            .Cells(i, 1).Value = cmt.Parent
            .Cells(i, 2).Value = cmt.Initial & cmt.Index
            .Cells(i, 3).Value = cmt.Scope
            If re.test(cmt.Range.text) Then
                Set colMatches = re.Execute(cmt.Range.text)
                For k = 1 To colMatches.Count
                    .Cells(i, 3 + k) = Trim(Replace(colMatches.Item(k - 1).Value, "[data]", ""))
                Next
            End If
        Next
    End With
    Set colMatches = Nothing
    Set re = Nothing
    Set xlWB = Nothing
    Set xlExcel = Nothing
End Sub

Nhớ là phải [data], tức không có dấu cách.

Cám ơn bạn nhiều lắm,

Gần đúng như mong muốn của bài toán rồi, tuy nhiên cần bổ sung thêm cột tiêu đề nữa, cụ thể như sau:

Kết quả của bạn đã xuất ra là:

A2: Schedule visit 10 to 18 March 2014 lgk.doc
B2: KLG1
C2: Dominique Chiesura
D2: Nội dung của tiêu đề Hành động bởi trong comments KLG1
E2: Nội dung của tiêu đề Thời gian thực hiện trong comments KLG1
F2: Nội dung của tiêu đề Sử dụng cho công việc trong comments KLG1

....

Mong muốn bài toán muốn xuất thêm cột cho phần tiêu đề (trong [Ti]):
A2: Schedule visit 10 to 18 March 2014 lgk.doc
B2: KLG1
C2: Dominique Chiesura
D2: Hành động bởi
E2: Nội dung của tiêu đề Hành động bởi trong comments KLG1
F2: Thời gian thực hiện
G2: Nội dung của tiêu đề Thời gian thực hiện trong comments KLG1
H2: Sử dụng cho công việc
I2: Nội dung của tiêu đề Sử dụng cho công việc trong comments KLG1

....

Thanks bạn siwtom nhé.
Khoi
 
Cám ơn bạn nhiều lắm,

Gần đúng như mong muốn của bài toán rồi, tuy nhiên cần bổ sung thêm cột tiêu đề nữa, cụ thể như sau:

Kết quả của bạn đã xuất ra là:

A2: Schedule visit 10 to 18 March 2014 lgk.doc
B2: KLG1
C2: Dominique Chiesura
D2: Nội dung của tiêu đề Hành động bởi trong comments KLG1
E2: Nội dung của tiêu đề Thời gian thực hiện trong comments KLG1
F2: Nội dung của tiêu đề Sử dụng cho công việc trong comments KLG1

....

Mong muốn bài toán muốn xuất thêm cột cho phần tiêu đề (trong [Ti]):
A2: Schedule visit 10 to 18 March 2014 lgk.doc
B2: KLG1
C2: Dominique Chiesura
D2: Hành động bởi
E2: Nội dung của tiêu đề Hành động bởi trong comments KLG1
F2: Thời gian thực hiện
G2: Nội dung của tiêu đề Thời gian thực hiện trong comments KLG1
H2: Sử dụng cho công việc
I2: Nội dung của tiêu đề Sử dụng cho công việc trong comments KLG1

....

Thanks bạn siwtom nhé.
Khoi

Nếu thế thì bạn phải mô tả dữ liệu để có thể cho dữ liệu vào đúng cell.
Vd. trong tập tin bạn có comment 3 là "[data]Nôi dung không tiêu đề [data]"
Tức D2 = "", E2 = "Nôi dung không tiêu đề", F2 = G2 = H2 = I2 = ""

Thế có th vd. comment = [data]Nôi dung 1[data][data]Nôi dung 2[data][Ti]Sử dụng cho công việc[Ti][data]Nôi dung 3[data]?
Và có thì D2 = "", E2 = "Nôi dung 1", F2 = "", G2 = "Nôi dung 2", H2 = "Sử dụng cho công việc", I2 = "Nôi dung 3"????

Thêm nữa, ở comment 3 ta có cặp [data...[data] mà không có cặp [Ti]...[Ti] ở đằng trước đi cùng. Thế có trường hợp chỉ có cặp [Ti]...[Ti] mà không có cặp [data]...[data] ở đằng sau đi cùng không?
 
Thưa bạn,

Nếu thế thì bạn phải mô tả dữ liệu để có thể cho dữ liệu vào đúng cell.
Vd. trong tập tin bạn có comment 3 là "[data]Nôi dung không tiêu đề [data]"
Tức D2 = "", E2 = "Nôi dung không tiêu đề", F2 = G2 = H2 = I2 = ""
<-- Đúng như bạn mô tả ở đây

Thế có th vd. comment = [data]Nôi dung 1[data][data]Nôi dung 2[data][Ti]Sử dụng cho công việc[Ti][data]Nôi dung 3[data]?
Và có thì D2 = "", E2 = "Nôi dung 1", F2 = "", G2 = "Nôi dung 2", H2 = "Sử dụng cho công việc", I2 = "Nôi dung 3"????
<-- Đúng như bạn mô tả ở đây

Thêm nữa, ở comment 3 ta có cặp [data...[data] mà không có cặp [Ti]...[Ti] ở đằng trước đi cùng. Thế có trường hợp chỉ có cặp [Ti]...[Ti] mà không có cặp [data]...[data] ở đằng sau đi cùng không?
<-- Nếu không có [Ti] ở đằng trước thì coi như để trống cell [Ti] đó thôi. Còn trường hợp chỉ có cặp [Ti]...[Ti] mà không có cặp [data]...[data] thì để trống cell [data]

Thanks
Khoi
 
Lần chỉnh sửa cuối:
Thưa bạn

Kết quả mong muốn như file đính kèm bạn nhé (Mình chỉ thêm cột thể hiện số trang mà comments xuất hiện).

Thanks
Khoi
 

File đính kèm

Lần chỉnh sửa cuối:
Thưa bạn,

<-- Đúng như bạn mô tả ở đây

<-- Đúng như bạn mô tả ở đây

<-- Nếu không có [Ti] ở đằng trước thì coi như để trống cell [Ti] đó thôi. Còn trường hợp chỉ có cặp [Ti]...[Ti] mà không có cặp [data]...[data] thì để trống cell [data]

Thanks
Khoi

Lúc trước bạn nói là chỉ có trường hợp có data mà không có Ti còn trường hợp có Ti mà không có data thì không sẩy ra. Bây giờ bạn lại nói là có cả trường hợp có Ti mà lại không có data
Mất công quá.
Mà tôi nghĩ là trường hợp không có tiêu đề (Ti) thì lôgíc nhưng trường hợp có Ti mà lại không có data = Nội dung thì không lôgíc, thừa, xóa cũng chả sao, không có cũng chả sao.

Vậy tôi loại trường hợp không có kiểu có Ti mà lại không có data. Bạn chấp nhận không?
Nếu chấp nhận thì code như ở sau.
-----------
Bạn thử test code này
Mã:
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, re As Object, colMatches As Object, SubMatch As Object
    Set xlExcel = CreateObject("Excel.Application")
    xlExcel.Visible = True
    Set xlWB = xlExcel.Workbooks.Add
    Set re = CreateObject("VBScript.RegExp")
    re.Global = True
    re.Pattern = "\[Ti](.*?)\[Ti] *\[data](.*?)\[data]|\[data](.*?)\[data]"
    i = 1
    With xlWB.Worksheets(1)
        For Each cmt In ActiveDocument.Comments
            i = i + 1
            .Cells(i, 1).Value = cmt.Parent
            .Cells(i, 2).Value = cmt.Initial & cmt.Index
            .Cells(i, 3).Value = cmt.Scope
            If re.test(cmt.Range.text) Then
                Set colMatches = re.Execute(cmt.Range.text)
                For k = 1 To colMatches.Count
                    Set SubMatch = colMatches.Item(k - 1).SubMatches
                    If SubMatch(2) = "" Then
                        .Cells(i, 2 * k + 2) = SubMatch(0)
                        .Cells(i, 2 * k + 3) = SubMatch(1)
                    Else
                        .Cells(i, 2 * k + 3) = SubMatch(2)
                    End If
                Next
            End If
        Next
    End With
    Set colMatches = Nothing
    Set SubMatch = Nothing
    Set re = Nothing
    Set xlWB = Nothing
    Set xlExcel = Nothing
End Sub
 
Thưa bạn

Kết quả mong muốn như file đính kèm bạn nhé (Mình chỉ thêm cột thể hiện số trang mà comments xuất hiện).

Thanks
Khoi

Tôi là người không thích cò cưa. Đã mô tả thì kỹ lưỡng và chỉ 1 hoặc cùng lắm 2 lần. Viết rồi sửa đi sửa lại mất công quá.
Lúc trước ở bài #9 Ti bắt đầu từ cột D. Bây giờ bạn đổi cấu trúc và Ti bắt đầu từ cột E.
Tôi viết lần cuối
Cột C là số thứ tự của trang.
Dữ liệu nếu chỉ có data thì không cần gõ Ti. Nhưng nếu bạn cứ muốn cả trường hợp có Ti nhưng không có data thì bạn tự làm vì tôi không sửa nữa. Tự làm thế nào? Bằng cách gõ thêm [data][data]. Tức vd. [Ti]gì đó[Ti][data][data]
Mã:
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, re As Object, colMatches As Object, SubMatch As Object
    Set xlExcel = CreateObject("Excel.Application")
    xlExcel.Visible = True
    Set xlWB = xlExcel.Workbooks.Add
    Set re = CreateObject("VBScript.RegExp")
    re.Global = True
    re.Pattern = "\[Ti](.*?)\[Ti] *\[data](.*?)\[data]|\[data](.*?)\[data]"
    i = 1
    With xlWB.Worksheets(1)
        For Each cmt In ActiveDocument.Comments
            i = i + 1
            .Cells(i, 1).Value = cmt.Parent
            .Cells(i, 2).Value = cmt.Initial & cmt.Index
            .Cells(i, 3).Value = cmt.Scope
            .Cells(i, 4) = cmt.Reference.Information(wdActiveEndAdjustedPageNumber)
            If re.test(cmt.Range.text) Then
                Set colMatches = re.Execute(cmt.Range.text)
                For k = 1 To colMatches.Count
                    Set SubMatch = colMatches.Item(k - 1).SubMatches
                    If SubMatch(2) = "" Then
                        .Cells(i, 2 * k + 3) = SubMatch(0)
                        .Cells(i, 2 * k + 4) = SubMatch(1)
                    Else
                        .Cells(i, 2 * k + 4) = SubMatch(2)
                    End If
                Next
            End If
        Next
    End With
    Set colMatches = Nothing
    Set re = Nothing
    Set xlWB = Nothing
    Set xlExcel = Nothing
End Sub
 
Tôi là người không thích cò cưa. Đã mô tả thì kỹ lưỡng và chỉ 1 hoặc cùng lắm 2 lần. Viết rồi sửa đi sửa lại mất công quá.
Lúc trước ở bài #9 Ti bắt đầu từ cột D. Bây giờ bạn đổi cấu trúc và Ti bắt đầu từ cột E.
Tôi viết lần cuối
Cột C là số thứ tự của trang.
Dữ liệu nếu chỉ có data thì không cần gõ Ti. Nhưng nếu bạn cứ muốn cả trường hợp có Ti nhưng không có data thì bạn tự làm vì tôi không sửa nữa. Tự làm thế nào? Bằng cách gõ thêm [data][data]. Tức vd. [Ti]gì đó[Ti][data][data]
Mã:
Sub CopyCommentsToExcel()
Dim xlExcel As Object
Dim xlWB As Object
Dim cmt As Word.Comment
Dim i As Integer, k As Integer, re As Object, colMatches As Object, SubMatch As Object
    Set xlExcel = CreateObject("Excel.Application")
    xlExcel.Visible = True
    Set xlWB = xlExcel.Workbooks.Add
    Set re = CreateObject("VBScript.RegExp")
    re.Global = True
    re.Pattern = "\[Ti](.*?)\[Ti] *\[data](.*?)\[data]|\[data](.*?)\[data]"
    i = 1
    With xlWB.Worksheets(1)
        For Each cmt In ActiveDocument.Comments
            i = i + 1
            .Cells(i, 1).Value = cmt.Parent
            .Cells(i, 2).Value = cmt.Initial & cmt.Index
            .Cells(i, 3).Value = cmt.Scope
            .Cells(i, 4) = cmt.Reference.Information(wdActiveEndAdjustedPageNumber)
            If re.test(cmt.Range.text) Then
                Set colMatches = re.Execute(cmt.Range.text)
                For k = 1 To colMatches.Count
                    Set SubMatch = colMatches.Item(k - 1).SubMatches
                    If SubMatch(2) = "" Then
                        .Cells(i, 2 * k + 3) = SubMatch(0)
                        .Cells(i, 2 * k + 4) = SubMatch(1)
                    Else
                        .Cells(i, 2 * k + 4) = SubMatch(2)
                    End If
                Next
            End If
        Next
    End With
    Set colMatches = Nothing
    Set re = Nothing
    Set xlWB = Nothing
    Set xlExcel = Nothing
End Sub

Trời đất, mình làm bạn mất công quá. Cho mình xin lỗi nhé.
Giờ đã hoàn toàn theo đúng ý mình rồi :)

Cám ơn bạn nhiều nhé. Bạn thật siêu VBA đấy.
Thanks siwtom
Khoi
 
Web KT

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

Back
Top Bottom