Ủ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
	=MID(A3,FIND("C",A3)+1,IFERROR( FIND("a150",A3),FIND("L",A3))-FIND("C",A3)-1)
	Cảm ơn bạn, hàm này nếu giá trị không phải "a150" thì nó không còn đúng nữa, nên sửa lại "FIND("a",A3)" thì sẽ đúng. Với lại mình đang muốn có code VBA để đồng bộ với file mình đang xây dựng.nếu chỉ có 2 dạng đó thôi thì hàm ếch vẫn xài
Mã:=MID(A3,FIND("C",A3)+1,IFERROR( FIND("a150",A3),FIND("L",A3))-FIND("C",A3)-1)