• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

Trao đổi về Word VBA Mời vào đây!

Nơi trao đổi về VBA (Visual Basic for Application), lập trình cho ứng dụng Microsoft Office, AutoCAD...

Điều hành viên: tungblt

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Replace All và vấn đề chiếm dụng RAM

Gửi bàigửi bởi truongphu » T.Sáu 08/03/2013 3:18 pm

Replace All và vấn đề chiếm dụng RAM

Trong các macro của Word (VBA), ứng dụng tìm và thay thế (Find and Replace) có nhiều ví dụ trong chủ đề nầy; mà câu lệnh thông thường là:
Selection.Find.Execute Replace:=wdReplaceAll
Bạn sẽ thấy một điều là bộ nhớ (RAM) nhanh chóng tụt thấp nếu dùng nhiều lần lệnh trên. Mà lệnh (code) là để mà dùng chứ không lẽ để ngắm?

Thông thường để edit một file doc khoảng 20 MB, dùng các lệnh Replace:=wdReplaceAll khoảng vài chục lần thì RAM khoảng 500 MB tự do dần dần tiêu thụ hết, Windows sau đó phải đẩy dữ liệu ra page.sys để giải phóng RAM, việc nầy khiến máy trở nên trì trệ

Trước đây để tránh việc nầy, mỗi lần RAM còn chừng 100 MB tôi lưu file và thoát Word, sau đó chạy lại; đương nhiên RAM sau khi Word.Close sẽ phục hồi, máy vẫn linh động. Tuy nhiên vẫn cảm giác "không sướng"!

Sở dĩ File dung lượng nhỏ nhiều so bộ nhớ, nhưng khi hoạt động .Execute Replace:=wdReplaceAll, lượng RAM nhanh chóng tiêu hao gấp nhiều lần vì Word tự động tạo ra trong RAM mỗi bản sao file doc đã được replace, số bản sao cứ tăng lên theo lệnh khiến cho RAM giảm nhanh chóng. Việc nầy chỉ chấm dứt khi ta hạ lệnh save và thoát Word. Động tác Save mà không thoát vẫn không giải phóng RAM vì Word vẫn giữ các bản sao cho Undo.

Mặt lợi của việc làm trên là thời gian xử lý nhanh chóng. Với máy mạnh (đa nhân đa luồng), vài GB RAM và file doc nhỏ vài chục MB, .Execute Replace:=wdReplaceAll là "vô tư"! Tuy nhiên với các biên tập viên có "hoàn cảnh" thao tác với chiếc PC "bèo" thì việc RAM tụt xuống zero quả là khó chịu. Nhanh đâu không thấy, chỉ làm việc mươi phút, máy đã ì ạch...

Sau đây là ví dụ một macro thông dụng, tìm "chúng ta" và thay với "các anh"

Mã: Chọn hết

Sub Macro1()
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "chúng ta"
        .Replacement.Text = "các anh"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
End Sub


Mặc dù code trên có vẻ dài thòng, nhưng tất cả chỉ là khai báo một lần trong cấu trúc With... End With
Như đã nói, việc hao tốn RAM chỉ là câu lệnh cuối:
Selection.Find.Execute Replace:=wdReplaceAll

Chấp nhận việc xử lý lâu một tí, bù lại RAM không giảm bao nhiêu (để duy trì máy linh hoạt), chúng ta đành từ bỏ câu lệnh
.Execute Replace:=wdReplaceAll
và dùng Sub TìmThayNgay thế cho câu lệnh trên:

Mã: Chọn hết

Sub TìmThayNgay()
Dim ZZZZ As Range
    Do While Selection.Find.Execute _
        (Replace:=wdReplaceNone, Forward:=True) = True
        Set ZZZZ = ActiveDocument.Range _
            (Start:=Selection.Start, End:=Selection.End)
        ZZZZ = Selection.Find.Replacement.Text
        Selection.MoveRight wdWord, 1, wdMove
    Loop
End Sub


Code trong Sub trên là một vòng lặp để tìm và thay Do... Loop
* Dòng 3 và 4 nối liền nghĩa là mỗi lần tìm có
* Dòng 5 và 6 nối liền và dòng 7 nghĩa là thay ngay trên file word giùm tôi
* Dòng 8 nghĩa là Con trỏ (Selection) dịch qua 1 chữ để tìm tiếp

Tôi bảo đảm với bạn nào có PC yếu cần biên tập trên MS Word dùng VBA, máy sẽ chạy êm, có điều: chậm một tí!

Code sửa toàn văn cho bạn nào chưa quen:

  1. Sub Macro2()
  2.     Selection.Find.ClearFormatting
  3.     Selection.Find.Replacement.ClearFormatting
  4.     With Selection.Find
  5.         .Text = "chúng ta"
  6.         .Replacement.Text = "các anh"
  7.         .Forward = True
  8.         .Wrap = wdFindContinue
  9.         .Format = False
  10.         .MatchCase = False
  11.         .MatchWholeWord = False
  12.         .MatchWildcards = False
  13.         .MatchSoundsLike = False
  14.         .MatchAllWordForms = False
  15.     End With
  16.     TìmThayNgay
  17. End Sub
  18.  
  19. Sub TìmThayNgay()
  20. Dim ZZZZ As Range
  21.     Do While Selection.Find.Execute _
  22.         (Replace:=wdReplaceNone, Forward:=True) = True
  23.         Set ZZZZ = ActiveDocument.Range _
  24.             (Start:=Selection.Start, End:=Selection.End)
  25.         ZZZZ = Selection.Find.Replacement.Text
  26.         Selection.MoveRight wdWord, 1, wdMove
  27.     Loop
  28. End Sub


Hay khong ? B-)

Chúc mừng các em gái trong forum nhân 8/3 @};-


o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » CN 10/03/2013 8:46 pm

Viết lại Sub TìmThayNgay vì thấy rườm rà...

  1. Sub TìmThayNgay()
  2.  With Selection.Find
  3.     .Execute Replace:=wdReplaceOne
  4.     While .Found
  5.         .Execute Replace:=wdReplaceOne
  6.     Wend
  7.  End With
  8. End Sub


;;)
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

hungtiensinh
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 06/05/2013 10:49 pm
Has thanked: 3 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi hungtiensinh » T.Hai 06/05/2013 11:44 pm

Nhờ các bác giúp đỡ
Tôi có các file, trong file có nhiều dòng, nhiều đoạn và nhiều trang nằm lẫn lộn giữa chữ và công thức chủ yếu chứa các phương trình phản ứng :
CaCl2+Na2CO3 --> CaCO3 + 2NaCl hoặc 1s2 2s2 2p6 3s1
..........................
Tôi muốn viết 1 đoạn code để các chữ màu đỏ xuống dưới và các chữ màu xanh lên trên.
Ý tưởng : cho vòng lặp chạy từ đầu đến cuối và có 2 biến xy. Nếu x là chữ và y là số thì định dạng y là chỉ số dưới. Nếu x là các chữ s,p,d,f và y là số thì sẽ định dạng y chỉ số trên.

Ý tưởng là vậy nhưng không thể viết code được !
Mong các bác giúp, chân thành cảm ơn !

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Tư 08/05/2013 5:16 pm

hungtiensinh đã viết:hungtiensinh

gớm! chắc anh bạn nầy lớn tuổi nhỉ!

hungtiensinh đã viết:có 2 biến xy

Dim X As String * 1, Y As String * 1
Đưa con trỏ về đầu bài
Selection.HomeKey Unit:=wdStory, Extend:=wdMove
hungtiensinh đã viết: cho vòng lặp chạy từ đầu đến cuối

Do Until Selection.Range.Bookmarks.Exists("\EndOfDoc") = True
'...
Loop


Trong vòng lặp, cho con trỏ lần lượt chọn 2 ký tự:
Selection.MoveRight Unit:=wdCharacter, Count:=2, Extend:=wdExtend
2 ký tự nầy phân phối cho 2 biến:
X = Left(Selection.Text, 1): Y = Right(Selection.Text, 1)

hungtiensinh đã viết:Nếu x là chữ và y là số thì định dạng y là chỉ số dưới. Nếu x là các chữ s,p,d,f và y là số thì sẽ định dạng y chỉ số trên.

* Nếu X là chữ và Y là số thì:
If (Not IsNumeric(X)) And (IsNumeric(Y)) Then
* Chọn bôi đen ký tự sau, và cho fontsize nhỏ lại:
Selection.Collapse Direction:=wdCollapseEnd
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Font.Size = 6

* Xem xét chữ gì:

Select Case X
Case "s", "p", "d", "f"
Selection.Font.Superscript = wdToggle 'nâng cao
Case " "
Case Else
Selection.Font.Subscript = wdToggle ' ha thâp
End Select


Code toàn vẹn và chạy êm như sau;
  1. Sub Macro1()
  2.     Dim X As String * 1, Y As String * 1
  3.     Selection.HomeKey Unit:=wdStory, Extend:=wdMove
  4.    
  5.     Do Until Selection.Range.Bookmarks.Exists("\EndOfDoc") = True
  6.     Selection.MoveRight Unit:=wdCharacter, Count:=2, Extend:=wdExtend
  7.     X = Left(Selection.Text, 1): Y = Right(Selection.Text, 1)
  8.     If (Not IsNumeric(X)) And (IsNumeric(Y)) Then
  9.             Selection.Collapse Direction:=wdCollapseEnd
  10.             Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
  11.             Selection.Font.Size = 6
  12.         Select Case X
  13.             Case "s", "p", "d", "f"
  14.             Selection.Font.Superscript = wdToggle
  15.             Case " "
  16.             Case Else
  17.             Selection.Font.Subscript = wdToggle
  18.         End Select
  19.     Selection.Collapse Direction:=wdCollapseEnd
  20.     Else
  21.     Selection.Collapse Direction:=wdCollapseStart
  22.     Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdMove
  23.     End If
  24.     Loop
  25. End Sub


Rõ ràng với code trên, các con số chỉ giới hạn 1 ký tự

Doc 2003:
Tập tin đính kèm
Phản ứng hóa học.rar
(7.49 KiB) Đã tải 205 lần
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

hungtiensinh
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 06/05/2013 10:49 pm
Has thanked: 3 time

`

Gửi bàigửi bởi hungtiensinh » T.Sáu 10/05/2013 11:54 pm

Rất cảm ơn bài viết kèm theo lời giải thích chu đáo của bác o0o--truongphu--o0o

Đúng là như vầy : 1s2 2s2 2p6 3s2
Nhưng nó bị như vầy :1s2 2s2 2p6 3s2

các chữ màu đỏ phải nằm ngang hàng với chữ s,p,d,f nhưng nó bị hạ xuống !
Khi ghé thăm bác chỉnh lại đôi chút nhé!
Chân thành cám ơn !

(Đây là file : http://www.mediafire.com/view/?n99v6xdq8a88r4o)

? Hoi thêm bác o0o--truongphu--o0o, nếu như mình viết bằng VB6 để sử dụng cho nhiều file, chứ không phải mỗi file đều phải chép macro để chạy, như vậy cần thiết thay câu lệnh nào trong đó.
(Về VB6 tôi cũng biết tí tí, xíu xíu về cách tạo form)
file : http://www.mediafire.com/?zzzz852sztxlql8

Thông tin thêm về nick hungtiensinh " Tâm hồn tuổi trẻ, sở thích của người già, tuổi gần trung niên"
Tôi là GV dạy Hóa đôi lúc trong giờ dạy hay lòng ghép kể chuyện ,.. để giảm bớt tính khô khan của môn học , riết rồi học trò nói giống ông già nên gọi là tiên sinh, chứ tuổi chưa có già, hihi!

wan
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 17/10/2011 10:51 am

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi wan » T.Sáu 17/05/2013 9:14 am

Hi Mr TruongPhu.

E có 1 câu hỏi sau đây muốn nhờ a giúp đỡ. Câu hỏi như sau ạ:
-Vd e có 1 file doc là nội dung của phần phụ lục pdf với 200 trang. Trong file doc có chương 1 là từ trang 1-70; 2 từ 71-150; 3 từ 151-200. Nội dung của file này như sau:
"Chuong 1 1
Hoi 1 2
Hoi 2 15
Hoi 3 35
Hoi 4 64
Chuong 2 71
Hoi 1 72
Hoi 2 120
Chuong 3 151
Hoi 1 152
Hoi 2 170"

*Với file phụ lục trên e muốn chèn 1 số thẻ ở trong các số trang của phụ lục. VD:

"Chuong 1 <a href="01_Chuong.html#ch1">1</a>
Hoi 1 <a href="01_Chuong.html#Hoi1">2</a>
Hoi 2 <a href="01_Chuong.html#Hoi2">15</a>
Hoi 3 <a href="01_Chuong.html#Hoi3">35</a>
Hoi 4 64
Chuong 2 71
Hoi 1 72
Hoi 2 120
Chuong 3 151
Hoi 1 152
Hoi 2 170"

E định thay thế trong word bằng wildcards các số rồi chèn thẻ trước, sau nhưng trong wildcards khi search nó không giới hạn số cần tìm rồi chỉ thay thế số đó. E muốn thay các chỉ các trang từ 1 tới 70 thôi nhưng search wildcards nó tìm rộng quá không giới hạn dc. A có biết cách nào giới hạn số cần tìm trong wildcards chỉ giúp e với.

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Sáu 17/05/2013 12:50 pm

wan đã viết:"Chuong 1 1

Có một em mê truyện!

wan đã viết:nhưng trong wildcards khi search nó không giới hạn số cần tìm rồi chỉ thay thế số đó. E muốn thay các chỉ các trang từ 1 tới 70 thôi nhưng search wildcards nó tìm rộng quá không giới hạn dc.

Nghĩa là bạn đã viết được 2 mẫu Selection.Find.TextSelection.Find.Replacement.Text
Trong tìm và thay, 2 điều trên là khó nhất...

wan đã viết:cách nào giới hạn số cần tìm trong wildcards chỉ giúp e với.

Thay vì bạn viết
Selection.Find.Execute Replace:=wdReplaceAll
chúng sẽ thay thế toàn bộ...

Ở đây, bạn muốn giới hạn trong 70 trang đầu. Con số nầy sẽ được nhận biết từ Selection.Find.Text, vd:
Hoi 2 15
Ta chỉ việc cho một biến để nhận giá trị nầy là xong!

Mã: Chọn hết

Dim ZZZZ As Range, MM() As String
        Do While Selection.Find.Execute _
        (Replace:=wdReplaceNone, Forward:=True) = True
            Set ZZZZ = ActiveDocument.Range _
            (Start:=Selection.Start, End:=Selection.End)
            MM = Split(ZZZZ.Text)
            If Int(MM(2)) > 70 then
              Exit Do
            else
             Selection.Find.Execute  Replace:=wdReplaceOne 
            end if   
        Loop

dòng 1: khai 2 biến: ZZZZ là Range để tiếp thu Selection.Find.Text và mảng String MM()
dòng 2: Chỉ cho tìm mà không thay
dòng 3: Khi tìm được thì: Cho biến ZZZZ nhận đối tượng đã tìm được
dòng 4: biến MM cắt Selection.Find.Text
dòng 5: so sánh phần tử MM(2) xem lớn hơn 70 không
Lớn hơn thì thoát
Nhỏ hơn thì chỉ thay 1 lần
Vòng lặp tiếp tục...

Kỹ thuật trên là kỹ thuật đọc được Selection.Find.Text khi nó biến đổi (wildcards)
Có nhiều bài viết tương tự trong chủ đề nầy, bạn đọc lại xem...
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

wan
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 17/10/2011 10:51 am

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi wan » T.Hai 20/05/2013 9:44 pm

Vâng. Để e ngâm cứu thêm. Có vấn đề nào khó hiểu xin dc a chỉ giáo thêm. E cảm ơn anh nhé.

wan
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 17/10/2011 10:51 am

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi wan » T.Ba 21/05/2013 3:45 pm

Mã: Chọn hết

Sub ThayTheTrongXML()
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "([A-z]{2,100}) ([0-9]{1,5})"
        .Replacement.Text = "\1 <b>\2</b>"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = True
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    ThayThe
End Sub
Sub ThayThe()
Dim ZZZZ As Range, MM() As String
        Do While Selection.Find.Execute _
        (Replace:=wdReplaceNone, Forward:=True) = True
            Set ZZZZ = ActiveDocument.Range _
            (Start:=Selection.Start, End:=Selection.End)
            MM = Split(ZZZZ.Text)
            If Int(MM(2)) > 70 Then
              Exit Do
            Else
             Selection.Find.Execute Replace:=wdReplaceOne
            End If
        Loop

End Sub


A xem giúp e code bên trên, khi e chạy báo "out of range". A có thể giải thích giúm e kỹ hơn ở phần "Sub ThayThe()" dc không. Dim ZZZ as range có tác dụng gì, as string là biến gì, và khi nào sử dụng nó dc không. Set ZZZ .... có tác dụng như thế nào??? E xin cảm ơn ạ

hungtiensinh
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 06/05/2013 10:49 pm
Has thanked: 3 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi hungtiensinh » T.Tư 19/06/2013 9:59 am

Chào anh chị em !
Tôi muốn viết một code (trong Word 2003) : textbox hoặc đối tượng shapes tự động di chuyển đến trang có chứa con trỏ. VD con trỏ ở trang 1 thì textbox trang 1. Nếu di chuyển con trỏ xuống trang 2 thì textbox di chuyển theo !
Anh chi em nào đã nghiên cứu hoặc có ý tưởng xin giúp dùm !
Chân thành cảm ơn !

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Tư 19/06/2013 6:10 pm

hungtiensinh đã viết:Nếu di chuyển con trỏ xuống trang 2 thì textbox di chuyển theo !


Khác với Excel: có sự kiện Worksheet_SelectionChange(ByVal Target As Range)
[Giải thích thêm: con trỏ ở excel luôn luôn xác định vùng ít nhất là 1 cell, cũng gọi là Selection]
Và vì Excel có sự kiện Worksheet_SelectionChange nên có thể thêm code kèm theo sự kiện nầy.

Trái lại, Word không có sự kiện SelectionChange hay tương đương,
do đó RẤT KHÓ VIẾT SỰ KIỆN MỖI KHI CON TRỎ THAY ĐỔI (SelectionChange)
[Nghĩa là thay đổi ngay lập tức khi con trỏ thay đổi]

Muốn, bạn phải:
1- Viết một sub riêng để đưa textbox về vị trí con trỏ hiện hành (selection)
Đương nhiên để chạy sub nầy phải qua 1 commandbutton hay phím tắt.
2- Để biến công việc hoàn toàn tự động: textbox theo con trỏ ngay lập tức; bạn phải:
- Chế tạo một Timer như VB6 (VBA không có control nầy)
- Code của Timer nầy: Bạn so sánh Selection.Text, nghĩa là mỗi lần con trỏ di chuyển, bạn ghi nhớ selection.text vào 1 biến string, sau đó cứ so sánh, Nếu giống thì thôi, nếu khác, chạy Sub đã viết ở mục 1

hungtiensinh đã viết:có ý tưởng xin giúp dùm !

Tôi chỉ giúp bạn cách làm; tiên liệu việc làm khá rối vì bạn phải vững về tạo các control VB6
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

caotrung
Bài viết: 3
Ngày tham gia: CN 20/05/2012 9:39 pm

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi caotrung » T.Năm 20/06/2013 12:42 pm

Chào các anh.
Em có một vặn bản word trong đó đã dùng chế độ xuống dòng và đặt kí tự tự động, ví dụ như:
A. aaaaaaaaaaaaaaa
B. bbbbbbbbbbbbbbb
C. ccccccccccccccc
D. ddddddddddddddd
E. eeeeeeeeeeeeeeee
................
Nghĩa là khi hết ý A và ấn enter thì văn bản tự động xuống dòng và điền B...............
Trong văn bản đã định dạng sẵn như vậy ở rất nhiều chỗ.
Bây giờ em muốn chuyển thành
A. aaaaaaaaaaaaaaa
B. bbbbbbbbbbbbbbb
C. ccccccccccccccc
D. ddddddddddddddd
E. eeeeeeeeeeeeeeee
nhưng phải bỏ được định dạng xuống dòng tự động.
Từ trước tới giờ em toàn làm việc đó thủ công. Tức là sửa từng ý một.
Vậy nhờ các anh trong diễn đàn viết giúp em một code macro để có thể sửa đồng loạt được không ạ.
Em chân thành cảm ơn các bác.

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Tư 10/07/2013 9:23 pm

caotrung đã viết:ấn enter thì văn bản tự động xuống dòng và điền B...............


File Word của bạn đã có macro
Bạn vào Visual Basic Editor, tìm và vô hiệu nó là xong
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Tư 10/07/2013 9:33 pm

Nguyen Van Cau đã viết:Mình có xem một số bài viết của anh trên trang web câu lạc bộ vb, có thấy nhiều lần anh trả lời ngắn gọn và hay quá, nên tính nhờ anh giúp cho viết cho 1 cái macro như sau, và xin gửi anh một ít chi phí gọi là để có quỹ uống cà phê cà pháo, quy ra đô là 5 hay 6 USD cho mỗi lần nhờ; nếu anh không phiền hà gì. Không biết như vậy là có thỏa đáng cho anh không, hay anh có ý kiến gì thì cứ cho biết, mình chưa quen. Thấy anh hay giải các bài toán như trang web, cũng có thể nhờ trên đó, nhưng vào Chuyện Linh Tinh của anh lại thấy địa chỉ email nên thử gửi; có ý muốn gửi thêm 1 tý bột cà phê ấy mà.
....
nó như thế này:
Mình có cái file word, muốn là : đặt con trỏ vào 1 từ nào đó/hoặc bôi đen cũng được. [thí dụ ở đây con trỏ nằm vào trong từ to ] . Sau đó bấm vào macro mà anh viết, nó sẽ :


1/ tạo ra 1 file .txt do người dùng đặt tên cho mỗi lần tạo và lưu vào đâu đó; file đó có chứa thông tin này:

- ghi từ to này với 3 từ khác trước và sau nó; và giảm dần đến 1 từ ở trước và sau; theo dạng sau [ví dụ] cho tất cả văn bản, và liệt kê hết ra.
trainer was able to communicate complex ideas
was able to communicate complex
able to communicate
TESTAMENTS to our QUALITY SERVICES
TESTAMENTS to our QUALITY
TESTAMENTS to our
any organisation looking to sharpen their negotiation
- - - - - - to - - - -
.....vv...


mặc định là con số 3 như thế, dĩ nhiên số này có thể thay đổi bằng mã VBA; hoặc đưa ra được lựa chọn thì quá tốt rồi (nhưng nếu vất vả cho anh thì bỏ qua)

để ý là các từ "to" xếp thẳng hàng với nhau.
các dấu đơn độc cũng kể như một từ, thí dụ viết sai chính tả thành to , and to ,
thì dấu , cũng được kể là một từ. Còn dấu nào đứng sát từ khác thì kể là thuộc về từ đó.

thí dụ các từ nào mà có dấu , liền kề thì cũng kể luôn dấu ấy thuộc từ đó cho nhanh như cụm từ này : , professional, , professional/lalala,
thì chọn luôn từ professional,
professional/lalala,
để sắp xếp.

(tất nhiên file .txt không bôi gì cả, anh biết đấy)


  1. Sub LàmTùyÝTheoYêuCâu()
  2. ' Tìm vi trí desktop trên máy bât ky (test trên HÐH WindowsXP / MS Word 2003)
  3. Dim DuongdanDesktop$
  4. Set objshell = CreateObject("Shell.Application").Namespace(0)
  5. DuongdanDesktop = objshell.Self.Path & "\"
  6. Dim NgàyGio$: NgàyGio = Format(Now, "ddmmyyyy-hhnn")
  7. Set objshell = CreateObject("Scripting.FileSystemObject").OpenTextFile(DuongdanDesktop & NgàyGio & ".txt", 8, 1, -1)
  8.  
  9. ' Yêu câu phai bôi Ðen tu Ðã chon
  10.    Dim jj%, sôtu%: sôtu = 3
  11.     Dim dòng$, Tìm$: Tìm = Selection.Text
  12.     With Selection.Find
  13.         .Text = Tìm
  14.     Do While Selection.Find.Execute _
  15.         (Replace:=wdReplaceNone, Forward:=True) = True
  16.  
  17.         For jj = sôtu To 1 Step -1
  18.         dòng = String(sôtu - jj, vbTab)
  19.         Selection.Collapse Direction:=wdCollapseStart
  20.         ' Kiêm tra ky không dính
  21.        Selection.MoveLeft wdCharacter, 1, wdExtend
  22.         If Selection.Text <> " " Then
  23.             Exit For
  24.         Else
  25.             Selection.Collapse Direction:=wdCollapseEnd
  26.         End If
  27.        
  28.         Selection.MoveLeft wdWord, jj, wdExtend
  29.         dòng = dòng & Selection.Text
  30.         Selection.Collapse Direction:=wdCollapseEnd
  31.         Selection.MoveRight wdWord, 1, wdExtend
  32.  
  33.         If Selection.Text <> Tìm Then Exit For
  34.  
  35.         dòng = dòng & Tìm
  36.  
  37.         Selection.Collapse Direction:=wdCollapseEnd
  38.         Selection.MoveRight wdWord, jj, wdExtend
  39.         dòng = dòng & Selection.Text
  40.  
  41.         Selection.Collapse Direction:=wdCollapseStart
  42.         Selection.MoveLeft wdWord, 1, wdExtend
  43.  
  44.         If Selection.Text <> Tìm Then Exit For
  45.        
  46.         objshell.Write dòng & vbCrLf
  47.         dòng = ""
  48.         Next
  49.         objshell.Write "- - - - - -" & vbCrLf
  50.         Selection.MoveRight wdWord, 1, wdMove
  51.     Loop
  52.    End With
  53. objshell.Close
  54. MsgBox "Ðã xong"
  55. End Sub
  56.  


Trong code trên, tôi đặt rất nhiều bẫy lỗi vì việc selection.move khá rối

===
Với bạn có lòng như: >:D<
có ý muốn gửi thêm 1 tý bột cà phê ấy mà.

TRUONG PHU
TK: 0581000543799
NGAN HANG NGOAI THUONG VIETCOMBANK
Phòng GD Cam Duc Cam lam Khanh Hoa

Nên chuyên qua ATM để phí chuyển nhẹ =D>
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Unicode tổ hợp và Unicode dựng sẵn

Gửi bàigửi bởi truongphu » T.Hai 15/07/2013 8:04 am

Trong các văn bản (word document, text), tiếng Việt unicode có thể biểu hiện lẫn lộn giữa unicode dựng sẵn và unicode tổ hợp; nếu nhìn bằng mắt thường rất khó phân biệt.

Ta xét thí dụ dãy ký tự có dấu đơn giản sau:
á à ả ã ạ
mỗi ký tự ta thấy, độ dài của chúng là 1 ký tự, có mã code là:
225 224 7843 227 7841
đấy là mã unicode quen thuộc: unicode dựng sẵn.

Nhưng chuỗi y chang sau:
á à ả ã ạ
thì mỗi ký tự gồm 2 ký tự gộp lại = độ dài là 2 ký tự;
mà ký tự đầu là ký tự a có mã code là 97
và ký tự sau sẽ có mã code theo thứ tự là 769 768 777 771 và 803
Trường hợp nầy lại là unicode tổ hợp.

Khi viết ứng dụng, nếu chúng ta dùng các lệnh có liên quan độ dài chuỗi như Len, Left, Mid, Right, kết quả có thể không như ý. nếu các lệnh nầy nằm trong vòng lặp, khi gặp điều kiện tương ứng, có thể dẫn đến vòng lặp vô hạn = treo máy!

Hoặc khi dùng sub Find and Replace, kết quả không toàn vẹn: vẫn còn chuỗi trong văn bản không đáp ứng.

Do đó để việc làm được êm xuôi, tốt nhất ta hãy thay các ký tự unicode tổ hợp sang unicode dựng sẵn. Vì văn bản chứa lẫn lộn 2 loại ký tự nên ta không thể chọn hết để chuyễn mã, mà phải dùng chức năng Find and Replace.
Bạn đọc có thể dùng vòng lặp, kết hợp hàm Mid để thay từng ký tự trong toàn văn bản. Tôi cung cấp 2 chuỗi dính liền sau:

Đây là chuỗi unicode tổ hợp (mỗi ký tự có Len = 2)
áàảãạắằẳẵặấầẩẫậéèẻẽẹếềểễệíìỉĩịóòỏõọốồổỗộớờởỡợúùủũụứừửữựýỳỷỹỵ

và đây là unicode dựng sẵn quen thuộc:
áàảãạắằẳẵặấầẩẫậéèẻẽẹếềểễệíìỉĩịóòỏõọốồổỗộớờởỡợúùủũụứừửữựýỳỷỹỵ

Hay không?
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

hungtiensinh
Thành viên chính thức
Thành viên chính thức
Bài viết: 10
Ngày tham gia: T.Hai 06/05/2013 10:49 pm
Has thanked: 3 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi hungtiensinh » T.Tư 07/08/2013 9:02 pm

Trong Word mình tô đen 1 đoạn văn bản, rồi xác định có bao nhiêu chữ a hoặc số 10 thì code VBA của word viết sau. ạ
(http://www.caulacbovb.com/forum/viewtop ... 15&t=21600) coi tới lui các bài viết nhưng trình độ yếu nên chưa biết cách làm !

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Năm 08/08/2013 9:24 am

hungtiensinh đã viết:tô đen 1 đoạn văn bản, rồi xác định có bao nhiêu chữ a hoặc số 10


1- lý thuyết:
Giải thuật đếm số ký tự trong chuỗi

2- Code:
http://truongphu111.blogspot.com/2012/0 ... uoi-1.html
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

tieulongnu_young
Thành viên chính thức
Thành viên chính thức
Bài viết: 12
Ngày tham gia: T.Tư 18/08/2010 3:58 pm

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi tieulongnu_young » T.Sáu 20/09/2013 11:33 am

Chào mọi người,

em có môt vấn đề cần mọi người giúp đỡ. Em đang làm một template trong word, tạo CV cho các chuyên gia của công ty. Trong mỗi template có một placeholder để chèn hình ảnh. Song song với template đó là một danh sách thông tin các chuyên gia dùng để mail merge (trộn thư). Tuy nhiên, em đang bó tay vì không tự động trộn thư cả hình ảnh luôn, mà phải chèn hình ảnh thủ công sau khi hoàn tất công tác trộn thư. Và nếu danh sách chuyên gia này lên đến 500 người thì có nghĩa là em phải làm đến 500 thao tác chèn hình. Có ai biết chỉ giúp em code này với, có thể trộn thư với cả hình ảnh luôn không ạ? Em cám ơn rất nhiều.

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4756
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 509 time

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi truongphu » T.Sáu 20/09/2013 2:23 pm

tieulongnu_young đã viết:một danh sách thông tin


Bạn nên dùng Access để làm csdl hơn là dùng Excel

tieulongnu_young đã viết:để mail merge (trộn thư)


Đương nhiên công việc nầy giao cho VBA làm. Word có hướng dẫn chức năng nầy: Menu Tools\ Letters and Mailing\ Mail Merge...

tieulongnu_young đã viết:em đang bó tay vì không tự động trộn thư cả hình ảnh luôn, mà phải chèn hình ảnh thủ công sau khi hoàn tất công tác trộn thư.


Đó là do bạn dùng csdl Excel.
Nếu bạn dùng Access, trong file mdb, các dòng thông tin trên các cột đều chuyển tải khi mail merge, kể cả cột hình!

Để đưa hình vào access, bạn dùng ADODB.Stream. Chi tiết, bạn xem thêm ở
95- Kỹ thuật ghi hình vào file MDB và load hình từ MDB ra Picture1

hoặc load project
Nhâp Anh và Load Anh.rar

Chúc bạn thành công
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

tieulongnu_young
Thành viên chính thức
Thành viên chính thức
Bài viết: 12
Ngày tham gia: T.Tư 18/08/2010 3:58 pm

Re: Trao đổi về Word VBA Mời vào đây!

Gửi bàigửi bởi tieulongnu_young » T.Sáu 20/09/2013 4:52 pm

Em cám ơn anh Trường Phú rất nhiều. Tuy nhiên, em nhờ anh làm rõ giúp em một tí:
- Theo như anh nói, em sẽ tạo một danh sách dùng để trộn thư bằng access, trong đó có trường hình ảnh, phải không ạ?
- Sau đó, trong access, em vào Alt_F11 để mở cửa sổ VBA lên, copy code dưới đây
[color=#400000]' Load hình anh vào MDB
Anh.LoadFromFile ("D:\MY DOCUMENTS\My Pictures\vet1.jpg")
Rec.Fields("hinhanh").Value = Anh.Read
Rec.Update
[/color]

Tuy nhiên em không rõ thao tác để đưa code này vào là làm như thế nào? Anh vui lòng chỉ chi tiết giúp em được không ạ?
Với tên trường là hinhanh thì các bản ghi em nên ghi như thế nào để chèn hình cho đúng? Các file hình ảnh em nên đưa vào một thư mục nhưng nên đặt tên file như thế nào?

Anh vui lòng chỉ giáo giúp em nhé! Cám ơn anh rất nhiều./.


Quay về “Visual Basic for Application (VBA)”

Đang trực tuyến

Đang xem chuyên mục này: Không có thành viên nào trực tuyến.1 khách