Ủa chi vậy bạn? Hàm MID trong VBA cũng có rồi, viết làm chi?Nhờ các cao thủ giúp em mã hoá bằng VBA thay cho hàm MID, như trong file đính kèm. Em chân thành cảm ơn!!!
Nhờ các cao thủ giúp em mã hoá bằng VBA thay cho hàm MID, như trong file đính kèm. Em chân thành cảm ơn!!!
Sub Main()
Dim lPos1 As Long, lPos2 As Long, lR As Long
Dim aSrc
Dim tmp1 As String, tmp2 As String
aSrc = Sheet2.Range("B8:B1000")
ReDim aDes(1 To UBound(aSrc, 1), 1 To 1)
For lR = 1 To UBound(aSrc, 1)
tmp1 = CStr(aSrc(lR, 1))
If Len(tmp1) Then
lPos1 = InStr(1, tmp1, "[")
If lPos1 Then
lPos2 = InStr(1, tmp1, "]")
If lPos2 Then
If lPos2 > lPos1 Then
tmp2 = Mid(tmp1, lPos1 + 1, lPos2 - lPos1 - 1)
aDes(lR, 1) = tmp2
End If
End If
End If
End If
Next
Sheet2.Range("C8").Resize(UBound(aDes, 1)).Value = aDes
End Sub
Nếu có chuỗi .....[10] thì sao? Ai mà chắc nhỉ? Ẹc... Ẹc...À, công thức của bạn thay vì:
=IF(B8<>0,ABS(MID(B8,FIND("[",B8,1)+1,(FIND("]",B8,1)-1)-(FIND("[",B8,1)))),"")
Thì có thể viết:
=IF(B8<>"",LEFT(RIGHT(B8,2)),"")
--------------------------
Nếu có chuỗi .....[10] thì sao? Ai mà chắc nhỉ? Ẹc... Ẹc...
Vì file chỉ đưa ra 9 mẫu, làm vậy cho lành! Còn không cũng có thể làm cái này nhỉ?
=IF(B8<>"",SUBSTITUTE(RIGHT(B8,LEN(B8)-FIND("[",B8)),"]",""),"")
Code vầy thử xem:
Mã:Sub Main() Dim lPos1 As Long, lPos2 As Long, lR As Long Dim aSrc Dim tmp1 As String, tmp2 As String aSrc = Sheet2.Range("B8:B1000") ReDim aDes(1 To UBound(aSrc, 1), 1 To 1) For lR = 1 To UBound(aSrc, 1) tmp1 = CStr(aSrc(lR, 1)) If Len(tmp1) Then lPos1 = InStr(1, tmp1, "[") If lPos1 Then lPos2 = InStr(1, tmp1, "]") If lPos2 Then If lPos2 > lPos1 Then tmp2 = Mid(tmp1, lPos1 + 1, lPos2 - lPos1 - 1) aDes(lR, 1) = tmp2 End If End If End If End If Next Sheet2.Range("C8").Resize(UBound(aDes, 1)).Value = aDes End Sub
Cám ơn thầy, em đã tính được kết quả nhưng làm sao để cột E tự động cập nhật hình dáng thanh thép. Hiện tại thì em click đúp vào thì nó mới cập nhật hình dáng thanh. Điều em cần là tự động cập nhật hình dáng thanh bằng 1 nút bấm. Thầy giúp em với.
Cám ơn thầy, em đã tính được kết quả nhưng làm sao để cột E tự động cập nhật hình dáng thanh thép. Hiện tại thì em click đúp vào thì nó mới cập nhật hình dáng thanh. Điều em cần là tự động cập nhật hình dáng thanh bằng 1 nút bấm. Thầy giúp em với.
Sub Main()
Dim lPos1 As Long, lPos2 As Long
Dim rng As Range, cel As Range
Dim tmp1 As String, tmp2 As String
Application.ScreenUpdating = False
Set rng = Sheet2.Range("B8", Sheet2.Range("B60000").End(xlUp))
For Each cel In rng
tmp1 = CStr(cel.Value)
If Len(tmp1) Then
lPos1 = InStr(1, tmp1, "[")
If lPos1 Then
lPos2 = InStr(1, tmp1, "]")
If lPos2 Then
If lPos2 > lPos1 Then
tmp2 = Mid(tmp1, lPos1 + 1, lPos2 - lPos1 - 1)
cel.Offset(, 1).Value = tmp2
End If
End If
End If
End If
Next
Application.ScreenUpdating = True
End Sub
Em đã làm được rồi, cảm ơn thầy đã giúp đỡ.Xem trong file là biết ngay thế nào cũng có yêu cầu này! Sao bạn không nêu ra ngay từ đầu cho người ta đở mất công?
Bây giờ sửa code lại duyệt theo từng cell bình thường:
Lý ra nếu có thời gian tôi sẽ làm bài này theo hướng khác hay hơn...Mã:Sub Main() Dim lPos1 As Long, lPos2 As Long Dim rng As Range, cel As Range Dim tmp1 As String, tmp2 As String Application.ScreenUpdating = False Set rng = Sheet2.Range("B8", Sheet2.Range("B60000").End(xlUp)) For Each cel In rng tmp1 = CStr(cel.Value) If Len(tmp1) Then lPos1 = InStr(1, tmp1, "[") If lPos1 Then lPos2 = InStr(1, tmp1, "]") If lPos2 Then If lPos2 > lPos1 Then tmp2 = Mid(tmp1, lPos1 + 1, lPos2 - lPos1 - 1) cel.Offset(, 1).Value = tmp2 End If End If End If End If Next Application.ScreenUpdating = True End Sub
Em up lại file, file trên bị lỗi.
Em tìm trên GPE có file thống kê cũng gần giống như file em đang làm, nhưng họ hình dáng thanh thép họ xuất sang không phải là hình mà là đối tượng vẽ trong excel luôn. Tiếc là file có password nên em không nghiên cứu được gì. Thầy xem giúp em với.Với số lượng 1000 dòng (tương ứng 1000 hình) và tương lai có thể nhiều hơn thế thì e rằng bạn nên xem lại...
- Thứ nhất: Số lượng hình ảnh quá nhiều sẽ khiến cho file nặng và chậm chạp
- Thứ hai: Chèn hình với số lượng lớn, code chạy không nỗi và có thể làm "treo" luôn Excel
Phải tính lại cách khác thôi
Em tìm trên GPE có file thống kê cũng gần giống như file em đang làm, nhưng họ hình dáng thanh thép họ xuất sang không phải là hình mà là đối tượng vẽ trong excel luôn. Tiếc là file có password nên em không nghiên cứu được gì. Thầy xem giúp em với.
Em đang chờ VBA mới tốt hơn của thầy.Khóa password rồi thì thôi, khỏi cần tham khảo... bởi vì cái của người ta chưa chắc gì đã ngon lành đâu
(tôi phát hiện nó vẽ chẳng chính xác tí nào)
Em đang chờ VBA mới tốt hơn của thầy.
Public Const strPath As String = "D:\TempPics"
Private Sub Auto_Open()
Dim cel As Range, IPic As IPictureDisp
Dim strFile As String
With CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(strPath) Then .CreateFolder strPath
For Each cel In [COLOR=#0000cd]Worksheets("Data").Range("B3:B11")[/COLOR]
Set IPic = [COLOR=#ff0000]PictureFromObject(cel)[/COLOR]
strFile = strPath & "\" & cel.Offset(, -1).Value & ".bmp"
SavePicture IPic, strFile
Next
End With
End Sub
Private Sub Auto_Close()
CreateObject("Scripting.FileSystemObject").DeleteFolder strPath
End Sub
Sub Main()
Dim lPos1 As Long, lPos2 As Long
Dim rng As Range, cel As Range, fso As Object
Dim tmp1 As String, tmp2 As String, strFile As String
On Error Resume Next
Application.ScreenUpdating = False
Set fso = CreateObject("Scripting.FileSystemObject")
Set rng = Sheet2.Range("B8", Sheet2.Range("B60000").End(xlUp))
For Each cel In rng
tmp1 = CStr(cel.Value)
If Len(tmp1) Then
lPos1 = InStr(1, tmp1, "[")
If lPos1 Then
lPos2 = InStr(1, tmp1, "]")
If lPos2 Then
If lPos2 > lPos1 Then
tmp2 = Mid(tmp1, lPos1 + 1, lPos2 - lPos1 - 1)
strFile = strPath & "\" & tmp2 & ".bmp"
cel.Offset(, 1).Value = tmp2
With cel.Offset(, 3)
.ClearComments
If fso.FileExists(strFile) Then
.AddComment: .Comment.Visible = True
With .Comment.Shape
.Shadow.Visible = msoFalse
.Line.ForeColor.RGB = vbWhite
.AutoShapeType = msoShapeRectangle
.Left = cel.Offset(, 3).Left: .Top = cel.Top
.Width = cel.Offset(, 3).Width: .Height = cel.Height
.ScaleWidth 0.9, msoFalse, msoScaleFromMiddle
.ScaleHeight 0.9, msoFalse, msoScaleFromMiddle
.Fill.UserPicture strFile
End With
End If
End With
End If
End If
End If
End If
Next
Application.ScreenUpdating = True
MsgBox "Cap nhat xong!"
End Sub
"Quá nhanh và quá nguy hiểm" tốc độ 3s/1000 row, thầy quá siêu.Không dám nói là tốt hơn nhưng cứ.. thử xem
Code vầy:
Trong file có dùng đến hàm PictureFromObject (tham khảo bên trong file nhé)Mã:Public Const strPath As String = "D:\TempPics" Private Sub Auto_Open() Dim cel As Range, IPic As IPictureDisp Dim strFile As String With CreateObject("Scripting.FileSystemObject") If Not .FolderExists(strPath) Then .CreateFolder strPath For Each cel In [COLOR=#0000cd]Worksheets("Data").Range("B3:B11")[/COLOR] Set IPic = [COLOR=#ff0000]PictureFromObject(cel)[/COLOR] strFile = strPath & "\" & cel.Offset(, -1).Value & ".bmp" SavePicture IPic, strFile Next End With End Sub Private Sub Auto_Close() CreateObject("Scripting.FileSystemObject").DeleteFolder strPath End Sub Sub Main() Dim lPos1 As Long, lPos2 As Long Dim rng As Range, cel As Range, fso As Object Dim tmp1 As String, tmp2 As String, strFile As String On Error Resume Next Application.ScreenUpdating = False Set fso = CreateObject("Scripting.FileSystemObject") Set rng = Sheet2.Range("B8", Sheet2.Range("B60000").End(xlUp)) For Each cel In rng tmp1 = CStr(cel.Value) If Len(tmp1) Then lPos1 = InStr(1, tmp1, "[") If lPos1 Then lPos2 = InStr(1, tmp1, "]") If lPos2 Then If lPos2 > lPos1 Then tmp2 = Mid(tmp1, lPos1 + 1, lPos2 - lPos1 - 1) strFile = strPath & "\" & tmp2 & ".bmp" cel.Offset(, 1).Value = tmp2 With cel.Offset(, 3) .ClearComments If fso.FileExists(strFile) Then .AddComment: .Comment.Visible = True With .Comment.Shape .Shadow.Visible = msoFalse .Line.ForeColor.RGB = vbWhite .AutoShapeType = msoShapeRectangle .Left = cel.Offset(, 3).Left: .Top = cel.Top .Width = cel.Offset(, 3).Width: .Height = cel.Height .ScaleWidth 0.9, msoFalse, msoScaleFromMiddle .ScaleHeight 0.9, msoFalse, msoScaleFromMiddle .Fill.UserPicture strFile End With End If End With End If End If End If End If Next Application.ScreenUpdating = True MsgBox "Cap nhat xong!" End Sub
Chỗ màu xanh là vùng Data của bạn, có thể sửa lại cho phù hợp (nếu có thay đổi)
------------------
Chạy thử xem tốc độ thế nào
Tuy nhiên khi in thì hình dáng thanh không thấy, thầy xem giúp em chỗ này
Cứ chạy code đi, tự cái cũ sẽ bị xóa thôivà em cần thêm cái VBA xóa hình dáng thanh cũ trước khi cập nhật cái mới. Cám ơn thầy rất nhiều.
Em hiểu ý thầy, nhưng vì nếu em copy 1 sheet mới từ sheet đã tính toán rồi nhưng dữ liệu có số dòng ít hơn thì nó sẽ thừa các hình dáng của sheet cũ.
Sub DelComm()
Sheet2.Range("E8:E60000").ClearComments
End Sub