Chuyên mục xử lý, gỡ rối code VBA (2 người xem)

Liên hệ QC

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

Status
Không mở trả lời sau này.

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,957
chào mọi người. tình hình là thầy giáo giao cho em nhiệm vụ lập trình vba để nhúng phần mềm thứ 3 là sap2000 để điều kiển sap2000? vậy cho e hỏi như thế có thể làm được không ạ? và độ khó cho 1 người chưa biết về vba là thế nào ạ? Em cảm ơn mọi người, hi vọng mọi người góp ý ạ!!!

Độ khó tuỳ thuộc vào mức độ "nhúng" và mức bảo mật của SAP. Cái này phải hỏi người quản lý cái phần mềm và csdl đó.
 
Upvote 0
2./Khi ra ngoài Excel gõ : SplitProvince(text,",")-->chạy không được.

Chạy không được tức là sao? Bạn hỏi nhiều ở đây rồi ít nhất cũng phải biết diễn tả "error gì gì đó, hay không ra đúng kết quả,..."
Trước mắt thì thấy: 1. dấu = đâu? 2. bạn có cái name nào tên là text để hàm nó duyệt chưa?
 
Upvote 0
Chào Anh Chị.
Em viết một hàm tự tạo, em test trong VBA thì chạy đúng, nhưng khi ra ngoài Excel gõ thì nó lại không ra kết quả. Anh Chị chỉ giúp lỗi để em sửa.
PHP:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
    Dim intdem As Integer
    Dim intPos As Integer
        For intdem = Len(Trim(Province)) To 1 Step -1
        If Mid(Province, intdem, 1) = delimiter Then
            intPos = intdem
            Exit For
        End If
        Next intdem
 SplitProvince = Trim(Right(Province, Len(Province) - intdem))
End Function
1./Khi test trong VBA, kết quả chạy ngon lành.
PHP:
Sub test()
    Cells(1, 2).Value = SplitProvince((Range("A1").Value), ",")
End Sub
2./Khi ra ngoài Excel gõ : SplitProvince(text,",")-->chạy không được.

Bạn muốn tìm vị trí cuối cùng của kí tự "delimiter" chăng ?
tìm hiểu thêm về hàm InStrRev có thể sẽ hữu ích cho bạn.
 
Upvote 0
Chào Anh Chị.
Em viết một hàm tự tạo, em test trong VBA thì chạy đúng, nhưng khi ra ngoài Excel gõ thì nó lại không ra kết quả. Anh Chị chỉ giúp lỗi để em sửa.
PHP:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
    Dim intdem As Integer
    Dim intPos As Integer
        For intdem = Len(Trim(Province)) To 1 Step -1
        If Mid(Province, intdem, 1) = delimiter Then
            intPos = intdem
            Exit For
        End If
        Next intdem
 SplitProvince = Trim(Right(Province, Len(Province) - intdem))
End Function
1./Khi test trong VBA, kết quả chạy ngon lành.
PHP:
Sub test()
    Cells(1, 2).Value = SplitProvince((Range("A1").Value), ",")
End Sub
2./Khi ra ngoài Excel gõ : SplitProvince(text,",")-->chạy không được.
Thì đương nhiên không chạy rồi. Ngoài bảng tính anh Bill có hiểu text là cái giống gì đâu chứ
Sao bạn không gõ: =SplitProvince(A1, ",")
???
Nói thêm là code này quá dài dòng
 
Upvote 0
Thì đương nhiên không chạy rồi. Ngoài bảng tính anh Bill có hiểu text là cái giống gì đâu chứ
Sao bạn không gõ: =SplitProvince(A1, ",")
???
Nói thêm là code này quá dài dòng

- Tối hôm qua, không hiểu gõ ra sao, mà nó không ra, giờ em gõ lại hàm thì nó ra rồi ạ.
- Nếu code dài dòng, xin Anh cho hướng để em tối ưu lại.
 
Upvote 0
Thì đương nhiên không chạy rồi. Ngoài bảng tính anh Bill có hiểu text là cái giống gì đâu chứ
Sao bạn không gõ: =SplitProvince(A1, ",")
???
Nói thêm là code này quá dài dòng

Em đổi lại như thế này, tối ưu chưa Anh ạ.
PHP:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
    Dim sArr() As String
    sArr = Split(Province, delimiter)
    SplitProvince = sArr(UBound(sArr, 1))
End Function
 
Upvote 0
Em có một sub như sau:
PHP:
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  Dim rTarget As Range, aTarget, i As Long, n As Long
  Dim Arr1(), Arr2(), Arr3(), tmp
  On Error Resume Next

  If Dic Is Nothing Then Auto_Open
  If Not Intersect(Range("C6:C10000"), Target) Is Nothing Then
    Set rTarget = Intersect(Range("C6:C10000"), Target)
    If IsArray(rTarget.Value) Then
      aTarget = rTarget.Value
...
Em để trong ThisWorkbook nhằm update thông tin nếu có sự thay đổi ở một cột chỉ định. Tuy nhiên có một sự bất tiện là có một sheet em không muốn sub này tác động đến thì em làm thế nào mà không phải xóa Sub này đi và add vào từng sheet trừ sheet mình không muốn tác động?
 
Upvote 0
Hi mọi người,

Do nhu cầu của công việc, mình đang phát triển macro để tự động gửi mail kèm attached file tới 1 nhóm người cố định

Yêu cầu :
- Một file / 1 e-mail
- Trên subject sẽ thể hiện tên file và 1 số thông tin thay đổi theo từng file.

Hướng làm của mình :
- Tất cả attached file, mình đều save vao ổ đĩa C
- Trong file excel, mình thể hiện các thông tin cần hiển thị trên subject e-mail.
( Mình có gửi hình chụp để mọi người tham khảo )

Mình đã viết đoạn code như sau :
Mã:
Sub TestSendEmail()
    Dim OutApp As Object
    Dim OutMail As Object
    
    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)
    
    On Error Resume Next
    
    With OutMail
        .To = "hoang.xuan@gmail.com"
        .CC = ""
        .BCC = ""
        .Subject = "Arrival Notice" & " " & Range("A2").Value & " " & Range("B2").Value & " " & Range("C2").Value & " " & Range("D2").NumberFormat
        .Body = "Please kindly see attached file"
        .Attachments.Add (Range("C6").Value & Range("A2").Value & ".pdf")
        .Send
    End With
    On Error GoTo 0
    
    Set OutMail = Nothing
    Set OutApp = Nothing


    MsgBox ("ARRIVAL NOTICE IS SENT TO CUSTOMER")

End Sub

Code đã chạy ok nhưng vấn đề của mình là code chỉ chạy dc cho dòng đầu tiên thôi. Mình muốn viết đoạn code để có thể chạy lần lượt cho tất cả các số trong cột HBL và subject e-mail thể hiện thông tin tương đương vs số HBL đó.

Mong mọi người hướng dẫn thêm.

Cám ơn rất nhiều
 

File đính kèm

  • VBA.jpg
    VBA.jpg
    70.1 KB · Đọc: 5
  • CODE.txt
    CODE.txt
    752 bytes · Đọc: 4
Upvote 0
Em đổi lại như thế này, tối ưu chưa Anh ạ.
PHP:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
    Dim sArr() As String
    sArr = Split(Province, delimiter)
    SplitProvince = sArr(UBound(sArr, 1))
End Function
Dùng InStrRev như bài 753 gợi ý sẽ tốt hơn
Ngoài ra bạn chưa tính đến mấy trường hợp sau:
1> Nếu không tìm thấy delimiter thì thế nào? Chẳng hạn theo file của bạn, nếu tôi gõ công thức =SplitProvince(A1,":") thì.. tè lè hết trơn
2> Trong mốt số trường hợp nào đó mà delimiter có đòi hỏi phân biệt HOA thường thì bạn tính sao? Chẳng hạn theo file của bạn nếu tôi gõ =SplitProvince(A1,"Cầ") thì kết quả OK trong khi nếu gõ =SplitProvince(A1,"cầ") lại... tè lè... tiếp
-------------------------
Nên nhớ rằng các hàm xử lý chuỗi trong VBA luôn luôn cung cấp cho ta kiểu so sánh (vbTextCompare hoặc vbBinaryCompare) mà không hiểu sao tôi thấy hầu hết mọi người thường ít để ý đến
Với code trên, nếu viết vầy:
Mã:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
  Dim sArr() As String
  If InStr(1, Province, delimiter, vbTextCompare) Then
    sArr = Split(Province, delimiter, , vbTextCompare)
    SplitProvince = sArr(UBound(sArr))
  End If
End Function
sẽ tốt hơn rất nhiều (theo ý kiến cá nhân tôi)
Còn tôi thì viết vầy:
Mã:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
  Dim lPos As Long
  lPos = InStrRev(Province, delimiter, , vbTextCompare)
  If lPos Then SplitProvince = Trim(Mid(Province, lPos + Len(delimiter)))
End Function
Hoặc tùy biến hơn:
Mã:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String, Optional ByVal CompareMode = vbTextCompare) As String
  Dim lPos As Long
  lPos = InStrRev(Province, delimiter, , CompareMode)
  If lPos Then SplitProvince = Trim(Mid(Province, lPos + Len(delimiter)))
End Function
Bạn thấy... sao?
 
Upvote 0
Dùng InStrRev như bài 753 gợi ý sẽ tốt hơn
Ngoài ra bạn chưa tính đến mấy trường hợp sau:
1> Nếu không tìm thấy delimiter thì thế nào? Chẳng hạn theo file của bạn, nếu tôi gõ công thức =SplitProvince(A1,":") thì.. tè lè hết trơn
2> Trong mốt số trường hợp nào đó mà delimiter có đòi hỏi phân biệt HOA thường thì bạn tính sao? Chẳng hạn theo file của bạn nếu tôi gõ =SplitProvince(A1,"Cầ") thì kết quả OK trong khi nếu gõ =SplitProvince(A1,"cầ") lại... tè lè... tiếp
-------------------------
Nên nhớ rằng các hàm xử lý chuỗi trong VBA luôn luôn cung cấp cho ta kiểu so sánh (vbTextCompare hoặc vbBinaryCompare) mà không hiểu sao tôi thấy hầu hết mọi người thường ít để ý đến
Với code trên, nếu viết vầy:
Mã:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
  Dim sArr() As String
  If InStr(1, Province, delimiter, vbTextCompare) Then
    sArr = Split(Province, delimiter, , vbTextCompare)
    SplitProvince = sArr(UBound(sArr))
  End If
End Function
sẽ tốt hơn rất nhiều (theo ý kiến cá nhân tôi)
Còn tôi thì viết vầy:
Mã:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String) As String
  Dim lPos As Long
  lPos = InStrRev(Province, delimiter, , vbTextCompare)
  If lPos Then SplitProvince = Trim(Mid(Province, lPos + Len(delimiter)))
End Function
Hoặc tùy biến hơn:
Mã:
Function SplitProvince(ByVal Province As String, ByVal delimiter As String, Optional ByVal CompareMode = vbTextCompare) As String
  Dim lPos As Long
  lPos = InStrRev(Province, delimiter, , CompareMode)
  If lPos Then SplitProvince = Trim(Mid(Province, lPos + Len(delimiter)))
End Function
Bạn thấy... sao?

- Em sẽ thay đổi theo hướng dùng hàm InStrRev, đồng thời bẫy lỗi và dùng kiểu so sánh với text, cho Function được hoàn thiện hơn.Cảm ơn Anh./
 
Upvote 0
Em có một sub như sau:
PHP:
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  Dim rTarget As Range, aTarget, i As Long, n As Long
  Dim Arr1(), Arr2(), Arr3(), tmp
  On Error Resume Next

  If Dic Is Nothing Then Auto_Open
  If Not Intersect(Range("C6:C10000"), Target) Is Nothing Then
    Set rTarget = Intersect(Range("C6:C10000"), Target)
    If IsArray(rTarget.Value) Then
      aTarget = rTarget.Value
...
Em để trong ThisWorkbook nhằm update thông tin nếu có sự thay đổi ở một cột chỉ định. Tuy nhiên có một sự bất tiện là có một sheet em không muốn sub này tác động đến thì em làm thế nào mà không phải xóa Sub này đi và add vào từng sheet trừ sheet mình không muốn tác động?
Bạn thêm đoạn code này vào đầu thủ tục, cái này sẽ làm cho nó không tác động vào sheet1.
Mã:
if sh is sheet1 then exit sub
 
Upvote 0
Hi mọi người,

Do nhu cầu của công việc, mình đang phát triển macro để tự động gửi mail kèm attached file tới 1 nhóm người cố định

Yêu cầu :
- Một file / 1 e-mail
- Trên subject sẽ thể hiện tên file và 1 số thông tin thay đổi theo từng file.

Hướng làm của mình :
- Tất cả attached file, mình đều save vao ổ đĩa C
- Trong file excel, mình thể hiện các thông tin cần hiển thị trên subject e-mail.
( Mình có gửi hình chụp để mọi người tham khảo )

Mình đã viết đoạn code như sau :
Mã:
Sub TestSendEmail()
    Dim OutApp As Object
    Dim OutMail As Object
 
    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)
 
    On Error Resume Next
 
    With OutMail
        .To = "hoang.xuan@gmail.com"
        .CC = ""
        .BCC = ""
        .Subject = "Arrival Notice" & " " & Range("A2").Value & " " & Range("B2").Value & " " & Range("C2").Value & " " & Range("D2").NumberFormat
        .Body = "Please kindly see attached file"
        .Attachments.Add (Range("C6").Value & Range("A2").Value & ".pdf")
        .Send
    End With
    On Error GoTo 0
 
    Set OutMail = Nothing
    Set OutApp = Nothing


    MsgBox ("ARRIVAL NOTICE IS SENT TO CUSTOMER")

End Sub

Code đã chạy ok nhưng vấn đề của mình là code chỉ chạy dc cho dòng đầu tiên thôi. Mình muốn viết đoạn code để có thể chạy lần lượt cho tất cả các số trong cột HBL và subject e-mail thể hiện thông tin tương đương vs số HBL đó.

Mong mọi người hướng dẫn thêm.

Cám ơn rất nhiều
Bạn tải code trong video về, và cấu hính như video là chạy được luôn.
httpssssss://www.youtube.com/watch?v=dcZEEBtIW4o
 
Upvote 0
Chào anh, chị.
Em có dùng đoạn code, mở từng File trong 01 thư mục được chỉ định, rồi copy lên File tổng hợp. Nhưng vì số lượng File lớn, mỗi lần mở file, copy dữ liệu rồi paste qua File TongHop. Em thấy làm vậy rất lâu.
- Không biết em có thể dùng mảng, để mỗi lần mở File lên.
+ Lưu hết dữ liệu vào mảng
+ Cuối cùng paste 01 lần vào File tổng hợp không?

Các Anh chị cho Em hướng để làm.
PHP:
Sub Copy_Database()
    Application.ScreenUpdating = False
    Application.AskToUpdateLinks = False
    Application.DisplayAlerts = False
    Application.Calculation = xlCalculationManual
    Range("A7:Z60000").ClearContents
    Dim rngVung As Range
    Dim strPath As String
    Dim fileName As String
    Dim NameFile As String
    strPath = Range("H1").Value
    fileName = Dir(strPath & "*.xls*")
    NameFile = ThisWorkbook.Name
    Do While fileName <> ""
        Workbooks.Open (strPath & fileName)
    
            ActiveWorkbook.ActiveSheet.Select
        If Application.WorksheetFunction.CountA(Range("A2:A60000")) > 0 Then
    
            Range("A2", Range("A60000").End(xlUp).Offset(0, 25)).Copy           ' Copy data Each a File
            Workbooks(NameFile).Sheets("Database").Range("A60000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues    ' Paste vao File tong hop
        End If
        Application.CutCopyMode = False
        ActiveWorkbook.Close SaveChanges:=False
        fileName = Dir()
    Loop
    Application.ScreenUpdating = True
    Application.Calculation = xlAutomatic
    Application.DisplayAlerts = True
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Bạn có code rồi thì cứ chạy thử 1, rồi 2, rồi 3 files xem sao.
Nếu không chạy được thì cho biết còn vướng chỗ nào.
 
Upvote 0
Bạn có code rồi thì cứ chạy thử 1, rồi 2, rồi 3 files xem sao.
Nếu không chạy được thì cho biết còn vướng chỗ nào.

Cảm ơn Anh.Hiện tại Em chạy ổn.
Em muốn tìm 01 giải pháp để làm nhanh hơn, hiện tại số lượng file của em lớn, tầm 300 file rồi.
 
Upvote 0
Copy file vào file là trường hợp cực chẳng đã, không phải là công việc thường xuyên và có tính chất lâu dài.
Miễn nó hoạt động đúng là được rồi, đâu cần phải nhanh.

Nếu việc copy data trở thành công việc thường xuyên thì phải xem lại quy trình làm việc của cty. Có thể dùng phương pháp khác sẽ dễ kiểm soát hơn.
Cứ vài ngày mà phải copy 300 files thì hơi lãng phí.
Nếu là tôi thì thử thí nghiệm cách nhận data theo dạng csv, append chúng vào thành 1 file rồi import vào file tổng. Import xuyên qua Access cũng là 1 cách kiểm soát tốt.
 
Upvote 0
Nhờ các thầy và các anh chỉnh sửa lại code giúp cho em với ạ.
- Khi Enter thì thời gian chạy không có vấn đề gì. Nhưng thời gian chạy lùi không chạy hẳn về "0:00" mà chỉ đến "0:01" rồi đánh chuông và chuyển sang thời gian nghỉ. Kể cả thời gian nghỉ chạy lùi cũng vậy, về đến "0:01" là đã đánh chuông rồi mà không phải là về hẳn "0:00". Do vậy mà thời gian nó như kiểu bị trễ giây ý ạ, và lúc chuyển sang thời gian nghỉ giữa hiệp nó cũng bị mất đi 1s đầu ạ.
---> Chỉnh lại giúp em là: Khi thời gian chạy lùi về "0:00" thì mới đánh chuông (Cả Thời gian thi đấu lẫn Thời gian nghỉ giữa hiệp), sau đó mới chuyển sang sự kiện tiếp theo.
Em cảm ơn ạ.
 

File đính kèm

Upvote 0
Các thầy và các anh có giải pháp gì không ạ?
 
Upvote 0
Nhờ các thầy và các anh chỉnh sửa lại code giúp cho em với ạ.
- Khi Enter thì thời gian chạy không có vấn đề gì. Nhưng thời gian chạy lùi không chạy hẳn về "0:00" mà chỉ đến "0:01" rồi đánh chuông và chuyển sang thời gian nghỉ. Kể cả thời gian nghỉ chạy lùi cũng vậy, về đến "0:01" là đã đánh chuông rồi mà không phải là về hẳn "0:00". Do vậy mà thời gian nó như kiểu bị trễ giây ý ạ, và lúc chuyển sang thời gian nghỉ giữa hiệp nó cũng bị mất đi 1s đầu ạ.
---> Chỉnh lại giúp em là: Khi thời gian chạy lùi về "0:00" thì mới đánh chuông (Cả Thời gian thi đấu lẫn Thời gian nghỉ giữa hiệp), sau đó mới chuyển sang sự kiện tiếp theo.
Em cảm ơn ạ.
Chả hiểu chi nữa, thử sửa cái này xem có đúng không?

Mã:
Private Sub DisplayTimer()
Dim i As Long
If Not Pause Then
    If Min = 0 And Sec <= 0 Then
 
Upvote 0
Chả hiểu chi nữa, thử sửa cái này xem có đúng không?

Mã:
Private Sub DisplayTimer()
Dim i As Long
If Not Pause Then
    If Min = 0 And Sec <= 0 Then
Hihi. Cảm ơn ạ. Chạy lùi về 0:00 ổn rồi ạ. Chỉ còn phần thời gian nghỉ giữa hiệp bị trễ mất 1s lúc đầu thôi ạ. Tiếp tục nhờ trợ giúp của mọi người.
 
Lần chỉnh sửa cuối:
Upvote 0
Status
Không mở trả lời sau này.
Web KT

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

Back
Top Bottom