Recently I changed my laptop and below given macro is not working in it. where as in my old machine it is still working. I cross checked all the references and enable it as per my old machine. I also cross checked with some other guys and they told me to use ADODB.Connection line in below code.
Also When I checked macro line by line items by pressing F8 key its is showing blank in "idapstr" line where as in old machine when using same macro its working fine.
Error code is on below line code "Set x = GetObject(ldapstr)" is mentioned below :-
**
" run time Error -2147023541 (8007054b)
Automation Error
The Specified domain either does not exist or could not be contacted."**
Can anybody help me out how to add the "ADODB.Connection" code or how to adjust this existing code ?
Public Sub UpdateResourceInfoNew()
Application.Calculation = xlCalculationManual
Dim auxDoc As New MSHTML.HTMLDocument, HTMLDoc As MSHTML.HTMLDocument
Dim rw As IHTMLTableRow
Dim table1 As IHTMLTable
Dim x As IADs
Dim lo As Excel.ListObject
Dim lr As Excel.ListRow
Dim rng As Range
Dim col As Column
Dim signum, name, ldapstr, relation As String
Dim urlText As Variant
Dim keyVal As Variant
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("ASSIGNMENTS")
Dim responseDict As Dictionary
On Error Resume Next
Dim answer As Integer
answer = MsgBox("Did you updated the Authorization Key in sheet ?", vbQuestion + vbYesNo)
If answer = vbYes Then
Set lo = ActiveWorkbook.Worksheets("ASSIGNMENTS").ListObjects("ASSIGNMENTS")
For Each lr In lo.ListRows
Set rng = lr.Range
signum = UCase(rng.Cells.Columns(lo.ListColumns("SIGNUM").Index).Value)
name = rng.Cells.Columns(lo.ListColumns("NAME").Index).Value
updateFlag = rng.Cells.Columns(lo.ListColumns("UPDATE_RES_INFO").Index).Value
If signum <> "" And updateFlag = 1 Then
ldapstr = "LDAP://CN=" & signum & ",OU=CA,OU=User,OU=P001,OU=ID,OU=Data,DC=XXXXXXXX,DC=se"
Set x = GetObject(ldapstr)
x.GetInfoEx Array("CN", "displayName", "givenName", , "email", "sn", "homePhone", "title", "department", "company", "l", "Manager", "country"), 0
auxCN = UCase(x.Get("CN"))
If (auxCN = signum) Then
rng.Cells.Columns(lo.ListColumns("SIGNUM").Index).Value = UCase(signum)
rng.Cells.Columns(lo.ListColumns("NAME").Index).Value = Application.WorksheetFunction.Proper(x.Get("displayName"))
rng.Cells.Columns(lo.ListColumns("RELATION").Index).Value = Application.WorksheetFunction.Proper(x.Get("homePhone"))
rng.Cells.Columns(lo.ListColumns("TITLE").Index).Value = x.Get("title")
rng.Cells.Columns(lo.ListColumns("DEPARTMENT").Index).Value = UCase(x.Get("department"))
rng.Cells.Columns(lo.ListColumns("COMPANY").Index).Value = UCase(x.Get("company"))
rng.Cells.Columns(lo.ListColumns("COUNTRY").Index).Value = UCase(x.Get("country"))
rng.Cells.Columns(lo.ListColumns("LAST NAME").Index).Value = Application.WorksheetFunction.Proper(x.Get("sn"))
rng.Cells.Columns(lo.ListColumns("FIRST NAME").Index).Value = Application.WorksheetFunction.Proper(x.Get("givenName"))
rng.Cells.Columns(lo.ListColumns("E-MAIL").Index).Value = x.Get("mail")
rng.Cells.Columns(lo.ListColumns("HOME BASE").Index).Value = UCase(x.Get("l"))
rng.Cells.Columns(lo.ListColumns("UPDATE_RES_INFO").Index).Value = 2
Set responseDict = New Dictionary
url_prefix = "XXXXXXX"
url_suffix = signum_rng
Application.DisplayAlerts = False
On Error Resume Next
Dim returnVal As String
Dim httpObject As Object, item As Object
Set httpObject = CreateObject("MSXML2.XMLHTTP")
URL = url_prefix & Trim(signum)
sAuthorization = Worksheets("Authentication key").Range("G4").Value
httpObject.Open "GET", URL, False
httpObject.setRequestHeader "Authorization", sAuthorization & EncodeBase64
httpObject.Send
sGetResult = httpObject.responseText
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.Send
urlText = Split(Replace(Replace(Replace(Replace(.responseText, "{", ""), "[", ""), "}", ""), "]", ""), ",""")
End With
responseDict.RemoveAll
For i = 0 To UBound(urlText)
urlText(i) = Replace(urlText(i), Chr(34), "")
keyVal = Split(urlText(i), ":")
responseDict.Add keyVal(0), keyVal(1)
Next i
If Split(urlText(34), ":")(1) <> "null" Or Len(Split(urlText(34), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("PERSONNEL NUMBER").Index).Value = Split(urlText(34), ":")(1)
End If
If Split(urlText(11), ":")(1) <> "null" Or Len(Split(urlText(11), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("JOB ROLE").Index).Value = Split(urlText(11), ":")(1)
End If
If Split(urlText(30), ":")(1) <> "null" Or Len(Split(urlText(30), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("POSITION NAME").Index).Value = Split(urlText(30), ":")(1)
End If
If Split(urlText(4), ":")(1) <> "null" Or Len(Split(urlText(4), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("LINE MANAGER").Index).Value = Split(urlText(4), ":")(1)
End If
If Split(urlText(38), ":")(1) <> "null" Or Len(Split(urlText(38), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("COUNTRY").Index).Value = Split(urlText(38), ":")(1)
End If
If Split(urlText(22), ":")(1) <> "null" Or Len(Split(urlText(22), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("MOBILE").Index).Value = Split(urlText(22), ":")(1)
End If
If Split(urlText(32), ":")(1) <> "null" Or Len(Split(urlText(32), ":")(1)) <> 0 Then
rng.Cells.Columns(lo.ListColumns("COST CENTRE").Index).Value = Split(urlText(32), ":")(1)
End If
Application.DisplayAlerts = True
Else
rng.Cells.Columns(lo.ListColumns("UPDATE_RES_INFO").Index).Value = 3
End If
End If
DoEvents
Next lr
MsgBox ("RP Updated")
Else
MsgBox "Please update the Authorization Key first"
End If
End Sub
I am trying to fetch few columns details from Active Directory based on user name in our code we are using as "Signum", due to basic user of VBA I am not able to find out the issue so come to this forum if any user any help me out.
Related
We have added 5 new columns to three sheets in a workbook. The first sheet is like a staging table that then populates the other two. The problem is the new columns are not being populated with the data in the two final sheets. The data is visible in the intial sheet. I think it may be an issue with the Advanced Filter but im not sure. Any help would be appreciated.
Public Sub RunExtract()
Dim strExtractYear As String
Dim strExtractMonth As String
Dim strOutputFolder As String
Application.ScreenUpdating = False
'grab the control variable values
strExtractYear = Range("Extract_Year").Value
strExtractMonth = Range("Extract_Month").Value
strOutputFolder = Range("Output_Folder").Value
'pull the data
Application.StatusBar = "Pulling data..."
Call PullData(strExtractYear, strExtractMonth)
'filter and output the results
Application.StatusBar = "Extracting 310 summary data..."
Range("SummaryFilter.Criteria").Cells(2, 2).Formula = "=""=310"""
Call FilterData(Range("SalesExtract.Table"), Range("SummaryFilter.Criteria"), Range("SummaryFilter.Header"), "SummaryFilter.Table")
Call OutputResults("SUMMARY", "310", strOutputFolder)
Application.StatusBar = "Extracting 430 summary data..."
Range("SummaryFilter.Criteria").Cells(2, 2).Formula = "=""=430"""
Call FilterData(Range("SalesExtract.Table"), Range("SummaryFilter.Criteria"), Range("SummaryFilter.Header"), "SummaryFilter.Table")
Call OutputResults("SUMMARY", "430", strOutputFolder)
Application.StatusBar = "Extracting 310 detail data..."
Range("DetailFilter.Criteria").Cells(2, 2).Formula = "=""=310"""
Call FilterData(Range("SalesExtract.Table"), Range("DetailFilter.Criteria"), Range("DetailFilter.Header"), "DetailFilter.Table")
Call OutputResults("DETAIL", "310", strOutputFolder)
Application.StatusBar = "Extracting 430 detail data..."
Range("DetailFilter.Criteria").Cells(2, 2).Formula = "=""=430"""
Call FilterData(Range("SalesExtract.Table"), Range("DetailFilter.Criteria"), Range("DetailFilter.Header"), "DetailFilter.Table")
Call OutputResults("DETAIL", "430", strOutputFolder)
Call CleanUpThisWorkbook
Application.StatusBar = "Done"
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Public Sub PullData(ExtractYear As String, ExtractMonth As String)
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim strStartDate As String
Dim strStartDateTime As String
Dim strEndDateTime As String
Dim strYear As String
Dim strMonth As String
Dim strLastDay As String
'clear the existing range
Range("SalesExtract.Table").CurrentRegion.Offset(1).EntireRow.Delete
'figure out the start and end datetimes
strYear = ExtractYear
strMonth = Right("0" & ExtractMonth, 2)
strStartDate = "{year}-{month}-{day}"
strStartDate = Replace(strStartDate, "{year}", strYear)
strStartDate = Replace(strStartDate, "{month}", strMonth)
strStartDate = Replace(strStartDate, "{day}", "01")
strStartDateTime = strStartDate & " 00:00:00"
strLastDay = CStr(Day(DateSerial(Year(strStartDate), Month(strStartDate) + 1, 0)))
strEndDateTime = "{year}-{month}-{day} 23:59:59"
strEndDateTime = Replace(strEndDateTime, "{year}", strYear)
strEndDateTime = Replace(strEndDateTime, "{month}", strMonth)
strEndDateTime = Replace(strEndDateTime, "{day}", strLastDay)
Private Sub OutputResults(Level As String, Company As String, Directory As String)
Dim wb As Workbook
Set wb = Workbooks.Add
Dim strSheet As String
If Level = "SUMMARY" Then
strSheet = "SummaryFilter"
ElseIf Level = "DETAIL" Then
strSheet = "DetailFilter"
Else
'raise error
End If
Call ThisWorkbook.Worksheets(strSheet).Range(strSheet & ".Table").Copy
Call wb.Worksheets(1).Range("A1").PasteSpecial(xlPasteValues)
Call ThisWorkbook.Worksheets(strSheet).Range(strSheet & ".ReplacementHeader").Copy
Call wb.Worksheets(1).Range("A1").PasteSpecial(xlPasteValues)
wb.Worksheets(1).Name = Level & " " & Company
Application.DisplayAlerts = False
Call wb.SaveAs(Directory & "\Sales Extract - " & Level & " " & Company & ".xlsx")
Application.DisplayAlerts = True
Call wb.Close
Set wb = Nothing
End Sub
Private Sub FilterData(FilterRng As Range, CriteriaRng As Range, CopyToRng As Range, NameMe As String, Optional FilterUnique As Boolean)
With CopyToRng
If WorksheetFunction.CountA(.Offset(1, 0).Resize(1, .Columns.Count)) <> 0 Then
CopyToRng.CurrentRegion.Offset(1, 0).ClearContents
End If
End With
FilterRng.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=CriteriaRng, _
CopyToRange:=CopyToRng, _
Unique:=FilterUnique
CopyToRng.CurrentRegion.Name = NameMe
End Sub
Private Sub CleanUpThisWorkbook()
Range("SalesExtract.Table").Offset(1).EntireRow.Delete
Range("SummaryFilter.Table").Offset(1).EntireRow.Delete
Range("DetailFilter.Table").Offset(1).EntireRow.Delete
End Sub
I have a script that exports specific range of cell from Excel to Word. Below you can see the script
Sub Export_to_Word_Mac()
Dim filename As String
Dim FolderName As String
Dim Folderstring As String
Dim FilePathName As String
Dim sh As Worksheet
Dim print_area As Range
Dim appWD As Object
Dim wddoc As Object
Dim rng As Range
Dim paragraphCount As Long
Set sh = ThisWorkbook.Sheets("Sheet1")
sh.Unprotect
sh.Rows("15:16").EntireRow.Hidden = True
For Each rng In sh.Range("B17:B26")
If rng.Value Like "wpisz zakres usług tutaj..." Then
rng.EntireRow.Hidden = True
Else
rng.EntireRow.Hidden = False
End If
Next rng
sh.Protect
FolderName = "Export"
filename = sh.Range("G4") & "_test_" & Format(Now, "dd-mm-yyyy_hhmm") & ".docx"
Folderstring = CreateFolderinMacOffice2016(NameFolder:=FolderName)
FilePathName = Folderstring & Application.PathSeparator & filename
On Error Resume Next
Set appWD = GetObject(, "Word.application")
If Err = 429 Then
Set appWD = CreateObject("Word.application")
Err.Clear
End If
Set wddoc = appWD.Documents.Add
appWD.Visible = True
With appWD.ActiveDocument.PageSetup
.TopMargin = appWD.InchesToPoints(0.5)
.BottomMargin = appWD.InchesToPoints(0.5)
.LeftMargin = appWD.InchesToPoints(0.5)
.RightMargin = appWD.InchesToPoints(0.5)
End With
'copy range to word
Set print_area = sh.Range("B1:C27")
print_area.Copy
'paste range to Word table
paragraphCount = wddoc.Content.Paragraphs.Count
wddoc.Paragraphs(paragraphCount).Range.Paste
Application.CutCopyMode = False
appWD.ActiveDocument.Tables(1).Rows.Alignment = wdAlignRowCenter
appWD.ActiveDocument.Cells.VerticalAlignment = wdCellAlignVerticalTop
'appWD.Activate
appWD.ActiveDocument.SaveAs (FilePathName)
MsgBox "Plik zostal zapisany jako: " & vbNewLine & filename & vbNewLine & _
" w nowo stworzonym " & FolderName & " w folderze: " & vbNewLine & "Library/Group Containers/UBF8T346G9.Office/"
appWD.Quit
Set wddoc = Nothing
Set appWD = Nothing
End Sub
Function CreateFolderinMacOffice2016(NameFolder As String) As String
Dim OfficeFolder As String
Dim PathToFolder As String
Dim TestStr As String
OfficeFolder = MacScript("return POSIX path of (path to desktop folder) as string")
OfficeFolder = Replace(OfficeFolder, "/Desktop", "") & _
"Library/Group Containers/UBF8T346G9.Office/"
PathToFolder = OfficeFolder & NameFolder
On Error Resume Next
TestStr = Dir(PathToFolder & "*", vbDirectory)
On Error GoTo 0
If TestStr = vbNullString Then
MkDir PathToFolder
'MsgBox "You find the new folder in this location :" & PathToFolder
End If
CreateFolderinMacOffice2016 = PathToFolder
End Function
Unfortunetely, there are a couple of issues:
It takes 1,5-2 minutes to export and save the Word file. Could you please help me to optimize the code?
I need to open Word application on my Mac to run the script. Otherwise I get Run-time error '9' (Script out of Range). The issue is with this line: Set appWD = GetObject(, "Word.application") .
The only solution I came up with is to use .CopyPicture xlScreen and paste it to Word document. I takes arpund 5 second create Word file, however the content is not editable and it is saved as image.
Option 1: Keep using Copy but optimize VBA execution
There are many options to improve speed execution in Excel VBA (see this articles for more details), but the most useful when copy-pasting is certainly to set :
Application.ScreenUpdating = False
However, since you are pasting in Word, you'd have to do the same this for the Word Application to get the maximum speed improvement:
appWD.ScreenUpdating = False
Note: Make sure to reset Application.ScreenUpdating = True at the end of your code.
Option 2 : Use an array to transfer the data
If the formatting of the cell in Excel is not necessary, then you could load the content of the cells into an array and write this array to the word document like this:
'copy range to word
Dim DataArray() As Variant
DataArray = sh.Range("B1:C27").Value
Dim i As Integer, j As Integer
Dim MyWordRange As Object
Set MyRange = appWD.ActiveDocument.Range(0, 0)
appWD.ActiveDocument.Tables.Add Range:=MyRange, NumRows:=UBound(DataArray, 1), NumColumns:=UBound(DataArray, 2)
'paste range to Word table
For i = 1 To UBound(DataArray, 1)
For j = 1 To UBound(DataArray, 2)
appWD.ActiveDocument.Tables(1).Cell(i, j).Range.Text = DataArray(i, j)
Next j
Next i
Note that option 1 and 2 are not necessarily mutually exclusives.
i need some help with the code below, i got this code on a tutorial and it`s working fine for me, the point of this question is, the code below only generate 1 PDF from a constant PDF Form, using Cells "A2" and "B2". How can i make a Loop, so the code generate 1 PDF file based on each row from sheet with text?
Im providing the code below. I would be very grateful for the help and time.
Option Explicit
Sub Write_to_pdf_form()
'declaring variables
Dim pdfApp As Acrobat.AcroApp
Dim pdfDoc As Acrobat.AcroAVDoc
Dim Support_doc As Acrobat.AcroPDDoc
Dim pdffile
Dim wsDocs As Worksheet
Dim outputname
'declaring output path
pdffile = "C:\Users\User\Documents\testesbulkpdf\Forms.pdf"
Dim pdf_form As AFORMAUTLib.AFormApp
'declaring fields
Dim num_doc As AFORMAUTLib.Field
Dim desc_doc As AFORMAUTLib.Field
Set pdfApp = CreateObject("AcroExch.App")
Set pdfDoc = CreateObject("AcroExch.AVDoc")
If pdfDoc.Open(pdffile, "") = True Then
pdfDoc.BringToFront
pdfApp.Show
'setting fields names
Set pdf_form = CreateObject("AFORMAUT.App")
Set num_doc = pdf_form.Fields("N")
Set desc_doc = pdf_form.Fields("descrição documento")
'setting fields values
num_doc.Value = Worksheets("docs").Range("A2").Value
desc_doc.Value = Worksheets("docs").Range("B2").Value
'setting output name of PDF
outputname = "Doc." & num_doc.Value & "-" & desc_doc.Value
Set Support_doc = pdfDoc.GetPDDoc
If Support_doc.Save(PDSaveFull, "C:\Users\User\Documents\testesbulkpdf\" & outputname & ".pdf") Then
Debug.Print "Saved"
Else
Debug.Print "Failed to save the doc"
End If
pdfDoc.Close True
Support_doc.Close
pdfApp.Exit
Set num_doc = Nothing
Set desc_doc = Nothing
Set pdfDoc = Nothing
Set Support_doc = Nothing
Set pdfApp = Nothing
End If
End Sub
I got it, using For Each, and some labels, i got it working just great.
For Each cell In Worksheets("docs").Range("A2:B500")
If cell.Value = "" Then
GoTo Line4
End If
If cell.Column = 1 Then
cell.Activate
If ActiveCell.Value <> "" Then
num_doc.Value = ActiveCell.Value
GoTo Line1
End If
End If
If cell.Column = 2 Then
cell.Activate
If ActiveCell.Value = "" Then
GoTo Line1
Else: desc_doc.Value = ActiveCell.Value
If desc_doc.Value <> "" And num_doc.Value <> "" Then
GoTo Line3
End If
End If
End If
If desc_doc Or num_doc = "" Then
GoTo Line4
End If
Line3:
outputname = "Doc." & num_doc.Value & "-" & desc_doc.Value
Set Support_doc = pdfDoc.GetPDDoc
If Support_doc.Save(PDSaveFull, "C:\Users\User\Documents\testesbulkpdf\" & outputname
& ".pdf") Then
Debug.Print "Saved"
Else
Debug.Print "Failed to save the doc"
End If
Line1:
Next cell
Line4:
pdfDoc.Close True
Support_doc.Close
pdfApp.Exit
Set num_doc = Nothing
Set desc_doc = Nothing
Set pdfDoc = Nothing
Set Support_doc = Nothing
Set pdfApp = Nothing
End Sub
I just started working with VBA.
I have a VBA code that counts the number of the occurence of words inside the excel file. It works fine.
I want to run this VBA macro on all files I have inside a specific folder.
Could you help me out?
My code below:
I am getting values right only for the file from which I ran the macro. For the rest of the files, the reults obtained are wrong
Sub LoopThroughFiles()
Dim xFd As FileDialog
Dim xFdItem As Variant
Dim xFileName As String
Set xFd = Application.FileDialog(msoFileDialogFolderPicker)
If xFd.Show = -1 Then
xFdItem = xFd.SelectedItems(1) & Application.PathSeparator
xFileName = Dir(xFdItem & "*.xls*")
Do While xFileName <> ""
With Workbooks.Open(xFdItem & xFileName)
Dim wordList As New Collection
Dim keyList As New Collection
Dim c
Worksheets("Sheet1").Activate
Dim RangeToCheck As Range
Set RangeToCheck = Range("A1:A1000")
For Each c In RangeToCheck
Dim words As Variant
words = Split(c, " ")
For Each w In words
Dim temp
temp = -1
On Error Resume Next
temp = wordList(w)
On Error GoTo 0
If temp = -1 Then
wordList.Add 1, Key:=w
keyList.Add w, Key:=w
Else
wordList.Remove (w)
keyList.Remove (w)
wordList.Add temp + 1, w
keyList.Add w, Key:=w
End If
Next w
Next c
Dim x
Dim k
k = 1
For x = 1 To wordList.Count
With Sheets("Sheet1")
.Cells(k, "E").Value = keyList(x)
.Cells(k, "F").Value = wordList(x)
k = k + 1
End If
End With
Next x
End With
xFileName = Dir
Loop
End If
End Sub
Try this
Public Sub LoopThroughFiles()
Dim xFd As FileDialog
Set xFd = Application.FileDialog(msoFileDialogFolderPicker)
xFd.AllowMultiSelect = False
If xFd.Show <> -1 Then
MsgBox "No Folder selected": Exit Sub
End If
Dim Folder As String: Folder = xFd.SelectedItems(1) & "\"
Dim Files
Files = Dir(Folder & "*.xls*")
Dim Xls As String
On Error Resume Next
Dim CrWB As Workbook, CrSheet As Worksheet
Dim ClnW As New Collection, ClnC As New Collection
Dim Cols As Integer: Cols = 1
Do While Files <> ""
Xls = Replace(Folder & Files, "\\", "\")
Set CrWB = Application.Workbooks.Open(Xls, , True)
Set CrSheet = CrWB.Sheets("Sheet1")
If Err.Number > 0 Then
MsgBox "Can't open File " & Xls & vbCrLf & Err.Description
Err.Clear
GoTo 1
End If
Dim c As Range
Set ClnW = New Collection: Set ClnC = New Collection
For Each c In CrSheet.Range("A1:A1000")
If c.Value <> "" Then
Words = Split(CStr(c.Value), " ", , vbTextCompare)
For Each s In Words
Err.Clear
tmp = ClnW(s)
If Err.Number > 0 Then
ClnW.Add Item:=s, Key:=s
ClnC.Add Item:=1, Key:=s
Else
x = ClnC(s) + 1
ClnC.Remove s
ClnC.Add Item:=x, Key:=s
End If
Next
End If
Next
Set CrSheet = ThisWorkbook.Sheets("Sheet1")
With CrSheet
.Cells(1, Cols).Value = Files
.Cells(2, Cols).Value = "Word"
.Cells(2, Cols + 1).Value = "Occurance"
.Range(.Cells(1, Cols), .Cells(1, Cols + 1)).Merge
Dim I As Integer: I = 3
For Each s In ClnW
.Cells(I, Cols).Value = s
.Cells(I, Cols + 1).Value = ClnC(s)
I = I + 1
Next
End With
Cols = Cols + 2
1
CrWB.Close False
Files = Dir()
Err.Clear
Loop
End Sub
I am using VBA in Autocad in order to count blocks in drawings.
With some search through the internet and some tries I have managed to complete the following code and count all blocks in any drawing, or by layer or the selected ones.
Sub BlockCount_Test()
dispBlockCount "COUNT_ALL"
dispBlockCount "COUNT_BY_LAYER"
dispBlockCount "COUNT_BY_FILTER"
End Sub
Sub dispBlockCount(ByVal strAction As String)
On Error Resume Next
Dim objBlkSet As AcadSelectionSet
Dim objBlkRef As AcadBlockReference
Dim strBlkNames() As String
Dim iGpCode(0) As Integer
Dim vDataVal(0) As Variant
Dim iSelMode As Integer
Dim iBlkCnt As Integer
iGpCode(0) = 0
vDataVal(0) = "INSERT"
iSelMode = 0 '|-- Selection Modes (0 = Select All, 1 = Select On Screen) --|
Set objBlkSet = getSelSet(iGpCode, vDataVal, iSelMode)
If objBlkSet.Count <> 0 Then
Select Case strAction
Case "COUNT_ALL"
ReDim strBlkNames(objBlkSet.Count - 1)
iBlkCnt = 0
For Each objBlkRef In objBlkSet
strBlkNames(iBlkCnt) = objBlkRef.Name
iBlkCnt = iBlkCnt + 1
Next
MsgBox getUniqBlockCount(strBlkNames), , "Count All"
Case "COUNT_BY_LAYER"
Dim objCadEnt As AcadEntity
Dim vBasePnt As Variant
ThisDrawing.Utility.GetEntity objCadEnt, vBasePnt, "Pick a block reference:"
If Err.Number <> 0 Then
MsgBox "No block references selected."
objBlkSet.Delete
Exit Sub
Else
If objCadEnt.ObjectName = "AcDbBlockReference" Then
Dim objCurBlkRef As AcadBlockReference
Dim strLyrName As String
iBlkCnt = 0
Set objCurBlkRef = objCadEnt
strLyrName = objCurBlkRef.Layer
For Each objBlkRef In objBlkSet
If StrComp(objBlkRef.Layer, strLyrName, vbTextCompare) = 0 Then
ReDim Preserve strBlkNames(iBlkCnt)
strBlkNames(iBlkCnt) = objBlkRef.Name
iBlkCnt = iBlkCnt + 1
End If
Next
MsgBox getUniqBlockCount(strBlkNames), , "Count by Layer"
Else
ThisDrawing.Utility.prompt "The selected object is not a block reference."
End If
End If
Case "COUNT_BY_FILTER"
Dim strFilter As String
iBlkCnt = 0
strFilter = ThisDrawing.Utility.GetString(False, "Enter a filter option:")
If strFilter <> "" Then
For Each objBlkRef In objBlkSet
If UCase(objBlkRef.Name) Like UCase(strFilter) Then
ReDim Preserve strBlkNames(iBlkCnt)
strBlkNames(iBlkCnt) = objBlkRef.Name
iBlkCnt = iBlkCnt + 1
End If
Next
MsgBox getUniqBlockCount(strBlkNames), , "Count by Filter"
Else
ThisDrawing.Utility.prompt "Search criteria should not be empty."
End If
Case Else
ThisDrawing.Utility.prompt "Invalid action mode."
End Select
Else
ThisDrawing.Utility.prompt "No block references were found."
End If
objBlkSet.Delete
If Err.Number <> 0 Then
ThisDrawing.Utility.prompt Err.Description
End If
End Sub
Function getSelSet(ByRef iGpCode() As Integer, vDataVal As Variant, iSelMode As Integer) As AcadSelectionSet
Dim objSSet As AcadSelectionSet
Set objSSet = ThisDrawing.SelectionSets.Add("EntSet")
Select Case iSelMode
Case 0
objSSet.Select acSelectionSetAll, , , iGpCode, vDataVal
Case 1
ReSelect:
objSSet.SelectOnScreen iGpCode, vDataVal
If objSSet.Count = 0 Then
Dim iURep As Integer
iURep = MsgBox("No entities selected, Do you want to select again?", _
vbYesNo, "Select Entity")
If iURep = 6 Then GoTo ReSelect
objSSet.Delete
Set getSelSet = Nothing
Exit Function
End If
Case Else
ThisDrawing.Utility.prompt "Invalid selection mode...."
End Select
Set getSelSet = objSSet
End Function
Function getUniqBlockCount(ByRef strBlkNames() As String) As String
Dim strUniqBlkNames() As String
Dim iBlkCount() As Integer
Dim iArIdx1, iArIdx2 As Integer
iArIdx1 = 0: iArIdx2 = 0
For iArIdx1 = LBound(strBlkNames) To UBound(strBlkNames)
If iArIdx1 = 0 Then
ReDim strUniqBlkNames(iArIdx2)
strUniqBlkNames(iArIdx2) = strBlkNames(iArIdx1)
iArIdx2 = iArIdx2 + 1
End If
Dim iUnqArIdx As Integer
Dim blUniq As Boolean
blUniq = True
For iUnqArIdx = LBound(strUniqBlkNames) To UBound(strUniqBlkNames)
If StrComp(strBlkNames(iArIdx1), strUniqBlkNames(iUnqArIdx), vbTextCompare) = 0 Then
blUniq = False
Exit For
End If
Next
If blUniq Then
ReDim Preserve strUniqBlkNames(iArIdx2)
strUniqBlkNames(iArIdx2) = strBlkNames(iArIdx1)
iArIdx2 = iArIdx2 + 1
End If
Next
iArIdx1 = 0: iArIdx2 = 0
For iArIdx1 = LBound(strUniqBlkNames) To UBound(strUniqBlkNames)
For iArIdx2 = LBound(strBlkNames) To UBound(strBlkNames)
If StrComp(strBlkNames(iArIdx2), strUniqBlkNames(iArIdx1), vbTextCompare) = 0 Then
ReDim Preserve iBlkCount(iArIdx1)
iBlkCount(iArIdx1) = iBlkCount(iArIdx1) + 1
End If
Next
Next
For iUnqArIdx = LBound(iBlkCount) To UBound(iBlkCount)
strUniqBlkNames(iUnqArIdx) = strUniqBlkNames(iUnqArIdx) & vbTab & vbTab & vbTab & iBlkCount(iUnqArIdx) & vbCrLf
Next
Dim strTitle, strBlkCount As String
strBlkCount = Join(strUniqBlkNames)
strTitle = "Block Name" & vbTab & vbTab & "Count" & vbCrLf
strTitle = strTitle & String(14, "-") & vbTab & vbTab & String(8, "-") & vbCrLf
getUniqBlockCount = strTitle & strBlkCount
End Function
My aim is to take these block numbers and insert them automatically in an excel sheet and in a certain sheet and cells.
Can someone help me find a solution to this problem?
I somehow managed to call an excel sheet but I am currently lost on how to put the block counts in the right position.
i.e. Let's say that I want them in a list as they present on the table I get from the count in my code, how could I achieve this?
P.S. I am new here and if you need any more info I would gladly add any more information needed in order to find a solution.
Thanks in advance
Georgia
I don't use AutoCad VBA myself, but based on the simple nature of your question, my guess is that this may help you on the road:
If you want to create a new Excel application:
Dim oApp_Excel as Excel.Application
Dim oBook as Excel.workbook
Set oApp_Excel = CreateObject("EXCEL.APPLICATION")
set oBook = oApp_Excel.workbooks.add
oBook.sheets("<Name>").cells(<Counter>, <Column_Number>).value = <BlockNr (based on counter)>
oBook.SaveAs(<Path>)
oBook.close
oApp_Excel.quit
set oBook = nothing
You can place the values in any cell or form you want; these are the basics of Excel VBA.
Another way is to load you BlockNumbers in an array first (in your current code) and then filling in values. This way you can set a range dynamically and load all the data from the array into the range at once.
I hope that I didn't misunderstand your question and that my reply serves your purpose.
'Create new excel instance.
Set excelApp = CreateObject("Excel.Application")
If err <> 0 Then
MsgBox "Could not start Excel!", vbExclamation, "Warning"
End
Else
excelApp.Visible = True
excelApp.ScreenUpdating = False
'Add a new workbook and set the objects.
Set wkbObj = excelApp.Workbooks.Add(1)
Set shtObj = excelApp.Worksheets(1)
shtObj.Name = "Measured Polylines"
With shtObj.Range("A1:D1")
.Font.Bold = True
.Autofilter
End With