Search not finding geometric set in tree CATIA Vba

I have a macro to join curves and everything works fine except for the search method. I if I set the In-work object to different geometric sets, the macro will find some of the sets, but not all of them. I am not sure why. The macro is supposed to paste the results into the current in-work geometric set.

This is the VBA Code I am working on:

Option Explicit

    '----------------------------------------------------------------
    '   Macro: Join_Explicit_No_Connect.bas
    '   Version: 1.0
    '   Code: CATIA VBA
    '   Release:   V5R32
    '   Purpose: Macro to join multiple un connected curves and isolates them
    '   Author: KaiUR
    '   Date: 13.09.24
    '----------------------------------------------------------------
    '
    '   Change:
    '
    '
    '----------------------------------------------------------------
    
Sub CATMain()
    CATIA.StatusBar = "Join_Explicit_No_Connect.bas, Version 1.0"    'Update Status Bar text
    
    'On Error Resume Next
    'On Error GoTo ErrorHandler
    
    '----------------------------------------------------------------
    'Declarations
    '----------------------------------------------------------------
    Dim PartDocumentCurrent As Document                             'Current Open Document
    Dim partCurrent As Part                                         'Current Open part
    Dim sel As CATBaseDispatch                                      'User Selection
    
    Dim InputObjectType(0) As Variant                               'iFilter for user input
    Dim Status As String                                            'Status of User selectin

    Dim Index As Integer                                            'Index for loops
    Dim cCount As Integer                                           'Curves Count

    Dim joinCurves As HybridShapeAssemble                           'New Join
    Dim RefCurves() As Reference                                    'Curve references
    
    Dim Wzk3D As CATBaseDispatch                                    'hybridshapefactory anchor
    Dim geoSet As HybridBody                                        'Geomeetric set
    Dim searchName As String                                        'Name of item to search
    
    Dim hybridShapesCount As Integer                                'Number of items in set
    
    Dim Error As Integer
    Dim PPRDocumentCurrent As PPRDocument                           'PPR Document
    
    '----------------------------------------------------------------
    'Open Current Document
    '----------------------------------------------------------------
    Set PartDocumentCurrent = CATIA.ActiveDocument                  'Current Open Document Anchor

    'If cat product is open, get first part, if no part exit macro
    If (Right(PartDocumentCurrent.Name, (Len(PartDocumentCurrent.Name) - InStrRev(PartDocumentCurrent.Name, "."))) = "CATProduct") Then
        If (PartDocumentCurrent.Product.Products.Count < 1) Then
            Error = MsgBox("No Parts found" & vbNewLine & "Please Open a .CATPart to use this script or Open part in new window", vbCritical)
            Exit Sub
        End If
        Set partCurrent = PartDocumentCurrent.Product.Products.Item(1).ReferenceProduct.Parent.Part
    'If cat process is open, get first part, if no part exit macro
    ElseIf (Right(PartDocumentCurrent.Name, (Len(PartDocumentCurrent.Name) - InStrRev(PartDocumentCurrent.Name, "."))) = "CATProcess") Then
        Set PPRDocumentCurrent = PartDocumentCurrent.PPRDocument    'Anchor PPR Document
        If (PPRDocumentCurrent.Products.Count < 1) Then
            Error = MsgBox("No Products Found" & vbNewLine & "Please Open a .CATPart to use this script or Open part in new window", vbCritical)
            Exit Sub
        End If
        Set partCurrent = PPRDocumentCurrent.Products.Item(1).ReferenceProduct.Parent.Part
    Else
        Set partCurrent = PartDocumentCurrent.Part                   'Current Open Part Anchor
    End If

    Set sel = PartDocumentCurrent.Selection                         'Set up user selection
    sel.Clear                                                       'Clear Selection
    
    '----------------------------------------------------------------
    'Get User selection
    '
    ' "MonoDimInfinite"  = Topological 1-D entity which may be infinite
    '
    '
    'CATMultiSelTriggWhenUserValidatesSelection
    '   Multi-selection is supported (through a dedicated "Tools Palette" toolbar).
    '   The selection (through a trap for example) is triggered when the user validates the selection.
    '   The CTRL and SHIFT keys are supported.
    '
    '----------------------------------------------------------------
    InputObjectType(0) = "MonoDimInfinite"                          'Set input type to curves
    'Get Input from User, get selections untill user acepts
    Status = sel.SelectElement3(InputObjectType, "Select curves to join", False, CATMultiSelTriggWhenUserValidatesSelection, False)
    
    If (Status = "Cancel") Then                                     'If User cancels or presses Esc, Exit Macro
        Exit Sub
    End If
    
    If sel.Count2 < 2 Then                                          'At least two things need to be selected
        Error = MsgBox("You need to select at least two curves", vbCritical)
        sel.Clear
        Exit Sub
    End If
    
    ReDim RefCurves(sel.Count2)                                     'Dynamic allocation acording to user input
    cCount = sel.Count2                                             'The amount of selected items
    For Index = 1 To sel.Count2                                     'Cycle through all inputs
        Set RefCurves(Index) = sel.Item2(Index).Reference           'Save selections to array
    Next
    sel.Clear                                                       'Clear Selection
    
    '----------------------------------------------------------------
    'Create new join
    '----------------------------------------------------------------
    Set Wzk3D = partCurrent.HybridShapeFactory                      'Anchor hybridshapefactory for use
    
    Set joinCurves = Wzk3D.AddNewJoin(RefCurves(1), RefCurves(2))   'Create new hybridshape assemble feature
    
    If cCount > 2 Then
        For Index = 3 To cCount                                     'Cycle through rest of curves
            joinCurves.AddElement RefCurves(Index)                  'Add curves to join
        Next
    End If
    
    joinCurves.SetAngularTolerance (0.5)                            'Set angle tol
    joinCurves.SetAngularToleranceMode (False)                      'Turn off angle tol mode
    joinCurves.SetConnex (False)                                    'Turn off check connex
    joinCurves.SetDeviation (0.001)                                 'Set merge distance
    joinCurves.SetFederationPropagation (0)                         'Set to no
    joinCurves.SetHealingMode (False)                               'No Heal
    joinCurves.SetSimplify (False)                                  'No simplify
    joinCurves.SetSuppressMode (True)                               'True is only option
    joinCurves.SetTangencyContinuity (False)                        'No tangent continuity
    joinCurves.SetManifold (True)                                   'Check Manifold
    
    searchName = partCurrent.InWorkObject.Name                      'Get name of in work object
    
    sel.Search "(NAME =" & searchName & "),all"                     'Search for in work object
    If (sel.Count2 <> 0) Then                                       'If result is found
        If sel.Item2(1).Type <> "Body" Then
            Set geoSet = sel.Item2(1).Value                          'Anchor geo set
        Else
            Set geoSet = partCurrent.HybridBodies.Add()              'Add New set
        End If
    Else
        Set geoSet = partCurrent.HybridBodies.Add()                  'Add New set
    End If
    sel.Clear                                                       'Clear Selection
    
    geoSet.AppendHybridShape joinCurves                             'Add join to set
    
    hybridShapesCount = geoSet.HybridShapes.Count                   'Number of items in set
    geoSet.HybridShapes.Item(hybridShapesCount).Name = "TEMP_JOIN"  'Rename Join
    
    partCurrent.Update                                              'Update Part
    
    '----------------------------------------------------------------
    'Create Datum
    '----------------------------------------------------------------
    sel.Search "(NAME =TEMP_JOIN),all"                              'Select temp_join
    sel.Copy                                                        'Copy
    sel.Clear                                                       'Clear Selection
    
    sel.Search "(NAME =" & geoSet.Name & "),all"                    'Select geoSet
    sel.PasteSpecial ("CATPrtResultWithOutLink")                    'Paste from clipboard as result without links
    sel.Clear                                                       'Clear selection
    
    hybridShapesCount = geoSet.HybridShapes.Count                   'Number of items in set
    sel.Search "(NAME =Join_Explicit.*),all"                         'Select all joins from this macro
    geoSet.HybridShapes.Item(hybridShapesCount).Name = "Join_Explicit." & sel.Count + 1 'Rename curve
    partCurrent.InWorkObject = geoSet.HybridShapes.Item(hybridShapesCount)
    sel.Clear                                                       'Clear Selection
    
    sel.Search "(NAME =TEMP_JOIN),all"                              'Select temp_join
    sel.Delete                                                      'Delete Selection
End Sub

The problems seem to be in this section:

    searchName = partCurrent.InWorkObject.Name                      'Get name of in work object
    
    sel.Search "(NAME =" & searchName & "),all"                     'Search for in work object
    If (sel.Count2 <> 0) Then                                       'If result is found
        If sel.Item2(1).Type <> "Body" Then
            Set geoSet = sel.Item2(1).Value                          'Anchor geo set
        Else
            Set geoSet = partCurrent.HybridBodies.Add()              'Add New set
        End If
    Else
        Set geoSet = partCurrent.HybridBodies.Add()                  'Add New set
    End If
    sel.Clear                                                       'Clear Selection

If I test the macro on a new file and create two curves and join them, it finds the geometric set and pastes in the result.

But in some files where the name of the geometric sets has been changes the macro cant find the set.
One example of a set it can`t find is when I name it “D40-09_NC CURVES” I am not sure why it cant find the set. It always seems to be able to fins the set if the name is the default name.

I tried removing spaces and adding underscores. I used Debug.Print to see what the string looked like that I was searching for. The name of the set and the name that I am looking for seem identical. If I use the same name in the search function from the edit menu it fins the set, but the query doesn’t work in the Vba code.

The search is not working the way I thought it should, perhaps I am using it incorrectly?

5

Alright, Thanks for the help and advice guys. I have modified my macro taking all the advice and suggestions into account.

I Have removed all Selection.Search calls from the macro and I walk the tree instead to find what I am looking for and this seems to be more stable and consistent.

Here is what I came up with now if anyone is interested:

Option Explicit

    '----------------------------------------------------------------
    '   Macro: Join_Explicit_No_Connect.bas
    '   Version: 1.0
    '   Code: CATIA VBA
    '   Release:   V5R32
    '   Purpose: Macro to join multiple un connected curves and isolates them
    '   Author: KaiUR
    '   Date: 13.09.24
    '----------------------------------------------------------------
    '
    '   Change:
    '
    '
    '----------------------------------------------------------------
    
Sub CATMain()
    CATIA.StatusBar = "Join_Explicit_No_Connect.bas, Version 1.0"    'Update Status Bar text
    
    On Error GoTo myErrorHandler
    
    '----------------------------------------------------------------
    'Defenitions
    '----------------------------------------------------------------
    Const finalJoinName = "Join_Explicit"                           'name for result from macro
    
    '----------------------------------------------------------------
    'Declarations
    '----------------------------------------------------------------
    Dim PartDocumentCurrent As Document                             'Current Open Document
    Dim partCurrent As Part                                         'Current Open part
    Dim sel As CATBaseDispatch                                      'User Selection
    
    Dim InputObjectType(0) As Variant                               'iFilter for user input
    Dim Status As String                                            'Status of User selectin

    Dim Index As Integer                                            'Index for loops
    Dim cCount As Integer                                           'Curves Count

    Dim joinCurves As HybridShapeAssemble                           'New Join
    Dim RefCurves() As Reference                                    'Curve references
    
    Dim Wzk3D As CATBaseDispatch                                    'hybridshapefactory anchor
    Dim geoSet As HybridBody                                        'Geomeetric set
    Dim searchName As String                                        'Name of item to search
    
    Dim hybridShapesCount As Integer                                'Number of items in set
    
    Dim Error As Integer
    Dim PPRDocumentCurrent As PPRDocument                           'PPR Document
    
    '----------------------------------------------------------------
    'Open Current Document
    '----------------------------------------------------------------
    Set PartDocumentCurrent = CATIA.ActiveDocument                  'Current Open Document Anchor

    'If cat product is open, get first part, if no part exit macro
    If (Right(PartDocumentCurrent.Name, (Len(PartDocumentCurrent.Name) - InStrRev(PartDocumentCurrent.Name, "."))) = "CATProduct") Then
        If (PartDocumentCurrent.Product.Products.count < 1) Then
            Error = MsgBox("No Parts found" & vbNewLine & "Please Open a .CATPart to use this script or Open part in new window", vbCritical)
            Exit Sub
        End If
        Set partCurrent = PartDocumentCurrent.Product.Products.Item(1).ReferenceProduct.Parent.Part
    'If cat process is open, get first part, if no part exit macro
    ElseIf (Right(PartDocumentCurrent.Name, (Len(PartDocumentCurrent.Name) - InStrRev(PartDocumentCurrent.Name, "."))) = "CATProcess") Then
        Set PPRDocumentCurrent = PartDocumentCurrent.PPRDocument    'Anchor PPR Document
        If (PPRDocumentCurrent.Products.count < 1) Then
            Error = MsgBox("No Products Found" & vbNewLine & "Please Open a .CATPart to use this script or Open part in new window", vbCritical)
            Exit Sub
        End If
        Set partCurrent = PPRDocumentCurrent.Products.Item(1).ReferenceProduct.Parent.Part
    Else
        Set partCurrent = PartDocumentCurrent.Part                   'Current Open Part Anchor
    End If

    Set sel = PartDocumentCurrent.Selection                         'Set up user selection
    sel.Clear                                                       'Clear Selection
    
    '----------------------------------------------------------------
    'Get User selection
    '
    ' "MonoDimInfinite"  = Topological 1-D entity which may be infinite
    '
    '
    'CATMultiSelTriggWhenUserValidatesSelection
    '   Multi-selection is supported (through a dedicated "Tools Palette" toolbar).
    '   The selection (through a trap for example) is triggered when the user validates the selection.
    '   The CTRL and SHIFT keys are supported.
    '
    '----------------------------------------------------------------
    InputObjectType(0) = "MonoDimInfinite"                          'Set input type to curves
    'Get Input from User, get selections untill user acepts
    Status = sel.SelectElement3(InputObjectType, "Select curves to join", False, CATMultiSelTriggWhenUserValidatesSelection, False)
    
    If (Status = "Cancel") Then                                     'If User cancels or presses Esc, Exit Macro
        Exit Sub
    End If
    
    If sel.Count2 < 2 Then                                          'At least two things need to be selected
        Error = MsgBox("You need to select at least two curves", vbCritical)
        sel.Clear
        Exit Sub
    End If
    
    ReDim RefCurves(sel.Count2)                                     'Dynamic allocation acording to user input
    cCount = sel.Count2                                             'The amount of selected items
    For Index = 1 To sel.Count2                                     'Cycle through all inputs
        Set RefCurves(Index) = sel.Item2(Index).Reference           'Save selections to array
    Next
    sel.Clear                                                       'Clear Selection
    
    '----------------------------------------------------------------
    'Create new join
    '----------------------------------------------------------------
    Set Wzk3D = partCurrent.HybridShapeFactory                      'Anchor hybridshapefactory for use
    
    Set joinCurves = Wzk3D.AddNewJoin(RefCurves(1), RefCurves(2))   'Create new hybridshape assemble feature
    
    If cCount > 2 Then
        For Index = 3 To cCount                                     'Cycle through rest of curves
            joinCurves.AddElement RefCurves(Index)                  'Add curves to join
        Next
    End If
    
    joinCurves.SetAngularTolerance (0.5)                            'Set angle tol
    joinCurves.SetAngularToleranceMode (False)                      'Turn off angle tol mode
    joinCurves.SetConnex (False)                                    'Turn off check connex
    joinCurves.SetDeviation (0.001)                                 'Set merge distance
    joinCurves.SetFederationPropagation (0)                         'Set to no
    joinCurves.SetHealingMode (False)                               'No Heal
    joinCurves.SetSimplify (False)                                  'No simplify
    joinCurves.SetSuppressMode (True)                               'True is only option
    joinCurves.SetTangencyContinuity (False)                        'No tangent continuity
    joinCurves.SetManifold (True)                                   'Check Manifold
    
    searchName = partCurrent.InWorkObject.Name                      'Get name of in work object
    Set geoSet = searchTreeGeo(searchName, partCurrent.HybridBodies) 'Search for in-Work GeoSet
    
    geoSet.AppendHybridShape joinCurves                             'Add join to set
    
    hybridShapesCount = geoSet.HybridShapes.count                   'Number of items in set
    
    partCurrent.Update                                              'Update Part
    
    '----------------------------------------------------------------
    'Create Datum
    '----------------------------------------------------------------
    sel.Add geoSet.HybridShapes.Item(hybridShapesCount)             'Select Temp Join
    sel.Copy                                                        'Copy
    sel.Clear                                                       'Clear Selection
    
    sel.Add geoSet                                                  'Select geoSet
    sel.PasteSpecial ("CATPrtResultWithOutLink")                    'Paste from clipboard as result without links
    sel.Clear                                                       'Clear selection
    
    hybridShapesCount = geoSet.HybridShapes.count                   'Number of items in set
    geoSet.HybridShapes.Item(hybridShapesCount).Name = setNameJoin(finalJoinName, partCurrent.HybridBodies)
    
    partCurrent.InWorkObject = geoSet.HybridShapes.Item(hybridShapesCount)
    sel.Clear                                                       'Clear Selection
    
    sel.Add geoSet.HybridShapes.Item(hybridShapesCount - 1)         'Select Temp Join
    sel.Delete                                                      'Delete Selection
    
    Exit Sub
    
myErrorHandler:
    'Handle part update errors and manifold errors
    If StrComp("Method 'Update' of object 'Part' failed", Err.Description, vbTextCompare) = 0 Then
        Error = MsgBox("Method 'Update' of object 'Part' failed." & vbNewLine & vbNewLine & "This can be caused by a Manifold error.", vbCritical)
        
        sel.Clear
        sel.Add geoSet.HybridShapes.Item(hybridShapesCount)
        sel.Delete
        Exit Sub
    'All other errors
    Else
        Error = MsgBox(Err.Description, vbCritical)
        Exit Sub
    End If
End Sub

'----------------------------------------------------------------
' Function to search for geometric set name in top level, then if not found
' it will call a recursive function on all sub levels untill found. If not found
' a new set will be added
'----------------------------------------------------------------
Function searchTreeGeo(searchName As String, currentHybridBodies As HybridBodies) As HybridBody
    Dim Index As Integer                                            'Index for loop

    If currentHybridBodies.count = 0 Then                           'If no geometric sets
        Set searchTreeGeo = currentHybridBodies.Add()               'Add new set
        Exit Function                                               'Exit
    End If
    
    For Index = 1 To currentHybridBodies.count                      'For all geometric sets
        If StrComp(searchName, currentHybridBodies.Item(Index).Name, vbTextCompare) = 0 Then    'If set name = search
            Set searchTreeGeo = currentHybridBodies.Item(Index)     'Save set
            Exit Function                                           'Exit
        Else
            If currentHybridBodies.Item(Index).HybridBodies.count > 0 Then  'If Sub Sets exist
                Set searchTreeGeo = searchTreeGeoRecursive(searchName, currentHybridBodies.Item(Index).HybridBodies)    'Call recursive search
            End If
        End If
    Next
    
    If searchTreeGeo Is Nothing Then                                    'If not found
        Set searchTreeGeo = currentHybridBodies.Add()                   'Add new Set
    End If
End Function

'----------------------------------------------------------------
' Recursive function to search for geometric set
'----------------------------------------------------------------
Function searchTreeGeoRecursive(searchName As String, currentHybridBodies As HybridBodies) As HybridBody
    Dim Index As Integer                                               'Index for loops

    For Index = 1 To currentHybridBodies.count                          'For all sets
        If StrComp(searchName, currentHybridBodies.Item(Index).Name, vbTextCompare) = 0 Then    'If found
            Set searchTreeGeoRecursive = currentHybridBodies.Item(Index)  'Save set
            Exit Function                                               'Exit
        Else
            If currentHybridBodies.Item(Index).HybridBodies.count > 0 Then  'If sub sets exist
                Set searchTreeGeoRecursive = searchTreeGeoRecursive(searchName, currentHybridBodies.Item(Index).HybridBodies)   'Call resursive this function
            End If
        End If
    Next
End Function

'----------------------------------------------------------------
' Function to search for all instnces of results from this macro.
'
' Will check top level geometric sets first, then recursivly go through lower levels
'----------------------------------------------------------------
Function setNameJoin(finalJoinName As String, currentHybridBodies As HybridBodies) As String
    Dim Index As Integer                                            'Index for loop
    Dim IndexShapes As Integer                                       'Index for loop
    Dim count As Integer                                            'Counts instances
    
    count = 1                                                       'Initilise count

    
    For Index = 1 To currentHybridBodies.count                      'For all geometric sets
        If currentHybridBodies.Item(Index).HybridShapes.count > 0 Then  'If elements exist
            For IndexShapes = 1 To currentHybridBodies.Item(Index).HybridShapes.count   'Loop all elements
                If InStr(1, currentHybridBodies.Item(Index).HybridShapes.Item(IndexShapes).Name, finalJoinName, vbTextCompare) <> 0 Then 'if found
                    count = count + 1                               'Increment count
                End If
            Next
        Else
            If currentHybridBodies.Item(Index).HybridBodies.count > 0 Then  'If geo sets exist
                count = count + setNameJoinRecursive(finalJoinName, currentHybridBodies.Item(Index).HybridBodies)   'Call recursive function
            End If
        End If
    Next
    
    setNameJoin = finalJoinName & "." & count                             'Set name
End Function

'----------------------------------------------------------------
' Recursive Function to search for all instnces of results from this macro.
'
'----------------------------------------------------------------
Function setNameJoinRecursive(finalJoinName As String, currentHybridBodies As HybridBodies) As String
    Dim Index As Integer                                                'Index for loop
    Dim IndexShapes As Integer                                          'Index for loop
    Dim count As Integer                                                'Counts instances
    
    count = 0                                                           'Initilise count
    
    For Index = 1 To currentHybridBodies.count                          'For all geometric sets
        If currentHybridBodies.Item(Index).HybridShapes.count > 0 Then  'If elements exist
            For IndexShapes = 1 To currentHybridBodies.Item(Index).HybridShapes.count   'Loop all elements
                If InStr(1, currentHybridBodies.Item(Index).HybridShapes.Item(IndexShapes).Name, finalJoinName, vbTextCompare) <> 0 Then   'If found
                    count = count + 1                                   'Increment Count
                End If
            Next
        Else
            If currentHybridBodies.Item(Index).HybridBodies.count > 0 Then  'If geo sets exist
                count = count + setNameJoinRecursive(finalJoinName, currentHybridBodies.Item(Index).HybridBodies)   'call this function on sets
            End If
        End If
    Next
    setNameJoinRecursive = count                                        'Set Counter
End Function

I am not sure if this is the most efficient way to do things, but it works all of the times that I have tested it. It always seems to find the In-Work geometric set.

If anyone has anymore suggestions let me know.

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật