Getting values from an autocad block attributes

Getting values from an autocad block attributes

dypro
Advocate Advocate
1,068 Views
13 Replies
Message 1 of 14

Getting values from an autocad block attributes

dypro
Advocate
Advocate

Hello everyone, I hope you can help me. I need:

 

1- A way to create a personalized iproperty if it does not exist.

2- A way to get the value from an attribute of an autocad block that is in the drawing already and place that value into the iproperty

3- A way to delete that block from the drawing afterwards. 

 

Thanks.

0 Likes
1,069 Views
13 Replies
Replies (13)
Message 2 of 14

WCrihfield
Mentor
Mentor

Hi @dypro.  I assume you are talking about working within an existing Inventor DrawingDocument, right?  If so, is it an DWG or IDW file type?  This does sound possible, because I have done some similar stuff before.  You would have to provide a lot more specific details about everything involved though, before anyone would be able to generate custom code for you to accomplish this very custom task.  Is the drawing one sheet, or multiple sheets?  Has this block been placed on every sheet, or just on one sheet, and if just on one sheet, which sheet?  Is there only one AutoCAD block in the drawing, or are there multiple?  If multiple, then what is the name of that block's definition (spelling and capitalization may both be important)?  What is the name (or other identifying traits) of the attribute within the block that you want to extract the value of?  It may also be important for us to know how many attributes are in that block.  What name do you want the new 'custom' iProperty to have?  Will this iLogic rule be one that is saved within the drawing document itself, or as an external iLogic rule, that can be used on many other documents?

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 14

dypro
Advocate
Advocate

Hello @WCrihfield, thanks for the answer, let's try to answer to all those questions so you people can help me.


-I assume you are talking about working within an existing Inventor DrawingDocument, right?

Yes
-If so, is it an DWG or IDW file type?
DWG
-Is the drawing one sheet, or multiple sheets?
It may be both
-Has this block been placed on every sheet, or just on one sheet, and if just on one sheet, which sheet?

In every sheet (but the attribs are the same on every sheet, so this may only be useful to the "delete" bit) 
-Is there only one AutoCAD block in the drawing, or are there multiple?
They may be several of them
-If multiple, then what is the name of that block's definition (spelling and capitalization may both be important)?
"SH_CAR_S" is the name, it may also be "Copia de SH_CAR_S" (i've encountered several drawings with the block with that crappy name, it means "copy of whatever block"). If one exists the other one does not.
-What is the name (or other identifying traits) of the attribute within the block that you want to extract the value of?

I want to extract almost every attribute within the block, the identifiers being as this photo:

dypro_1-1685601621178.png

I don't need the ones in red.

I just asked for extracting one so I could copy paste the code several times, and you didn't have to make every line.

 

-It may also be important for us to know how many attributes are in that block. 

They are 26, being the ones in the photo the first 22

 

-What name do you want the new 'custom' iProperty to have?

The same thing as before is for the custom iproperties, I asked for one, so I could copy paste ir an do it several times.
The iproperties are as follows:

dypro_2-1685601945980.png

 

-Will this iLogic rule be one that is saved within the drawing document itself, or as an external iLogic rule, that can be used on many other documents?

As an external rule, obviously I don't want to make you do all this work for one drawing, they are lots of drawings on witch this rule is going to be used. 😆

 

As a bonus, here is a "how does it match":

dypro_3-1685603044119.png


I hope this makes clear every point, and thanks. 

 

0 Likes
Message 4 of 14

WCrihfield
Mentor
Mentor

Hi @dypro.  This is a fairly complex scenario, and highly custom, so I did not completely finish the code I created for it, but I got you most of the way there.  There is a point down near the end of the code, where you can see that I have left you a comment to continue the pattern of code that I started, because it needs many very similar blocks of code, one for each possible 'prompt', 'value', & custom iProperty grouping.  I could have created one or more externally referenced Sub/Function type routines to help eliminate some of the repetitiveness, but I decided to keep it as simple as possible for you right now, which usually means keeping it all in one logical piece, and flowing from top to bottom in one long process.  I included several lines of comments, but probably could have included many more comments.  If you still need help with this, feel free to post back here again.

Sub Main
	'make sure we are working with a drawing...if not let user know, and exit the rule
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
		MsgBox("A Drawing document must be active for this code to work. Exiting.", vbCritical, "")
		Exit Sub
	End If
	Dim oDDoc As DrawingDocument = ThisDoc.Document
	Dim oACBDs As AutoCADBlockDefinitions = oDDoc.AutoCADBlockDefinitions
	If oACBDs.Count = 0 Then Exit Sub 'none found in drawing, so exit the rule
	'this next variable will be used to store the block definition we are trying to find, when found
	Dim oTargetACBD As AutoCADBlockDefinition = Nothing
	'store the two possible names of the block definition we are looking for
	Dim PossibleBlockDefNames() As String = {"SH_CAR_S", "Copia de SH_CAR_S" }
	'loop through the AutoCADBlockDefinitions, to find the one we are after
	For Each oACBD As AutoCADBlockDefinition In oACBDs
		'if the block definition is not being referenced (no placed blocks for it), try to delete it
		'if an instance of it has not been placed, there will not be any values to get
		If oACBD.IsReferenced = False Then Try : oACBD.Delete : Catch : End Try
		'loop through the two possible names for the block definition
		For Each BlockDefName In PossibleBlockDefNames
			If oACBD.Name = BlockDefName Then
				oTargetACBD = oACBD
				Exit For 'exits this inner loop
			End If
		Next 'BlockDefName
		If oTargetACBD IsNot Nothing Then Exit For 'exit outer loop if target already found
	Next 'oACBD
	If IsNothing(oTargetACBD) Then Exit Sub 'the definition was not found, so exit rule
	
	'we must prepare the variables ahead of time, then this method fills in their values
	Dim oTags() As String = {}
	Dim oPrompts() As String = {}
	oTargetACBD.GetPromptTags(oTags, oPrompts)
	If oPrompts.Length = 0 Then Exit Sub 'the block definition does not have any prompts, so exit rule
	'these next two lines are simply for research & feedback, you can comment them out if you want
	oTagx = InputListBox("", oTags, "", oTargetACBD.Name & " Tags", "List Of Tags")
	oPromptx = InputListBox("", oPrompts, "", oTargetACBD.Name & " Prompts", "List Of Prompts")

	'get a reference to the drawing's 'Custum' iProperty set, for use later within the loop
	Dim oCProps As Inventor.PropertySet = oDDoc.PropertySets.Item(4)

	'now loop through the sheets to find placed blocks referencing the definition
	Dim oSheets As Inventor.Sheets = oDDoc.Sheets
	For Each oSheet As Inventor.Sheet In oSheets
		Dim oACBs As AutoCADBlocks = oSheet.AutoCADBlocks
		If oACBs.Count = 0 Then Continue For 'skip to next sheet if no blocks on this sheet
		For Each oABC As AutoCADBlock In oACBs
			'if the definition this block is referencing is not our 'target' one, then skip to next block
			If oABC.Definition IsNot oTargetACBD Then Continue For
			'again, we must prepare the variables first, then this method fills in their values
			Dim oPromptTags() As String = {}
			Dim oValues() As String = {}
			oABC.GetPromptTextValues(oPromptTags, oValues)
			If oPromptTags.Length = 0 Then Continue For 'there were no prompts, so skip to next
			'again, these next two lines are simply for research & feedback
			oPromptTagx = InputListBox("", oPromptTags, "", oABC.Name & " PromptTags", "List Of PromptTags")
			oValuex = InputListBox("", oValues, "", oABC.Name & " Values", "List Of Values")
			For i As Integer = 0 To UBound(oPromptTags)
				Dim sPromptTag As String = oPromptTags(i)
				Dim sValue As String = oValues(i)
				Dim oCProp As Inventor.Property = Nothing
				Select Case sPromptTag
					Case "SH_AFFAI"
						Try : oCProp = oCProps.Item("NUMERO INSTALACION")
						Catch : oCProp = oCProps.Add(sValue, "NUMERO INSTALACION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_PARTI"
						Try : oCProp = oCProps.Item("CODIGO DE PARTICION")
						Catch : oCProp = oCProps.Add(sValue, "CODIGO DE PARTICION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_MODUL"
						'<<<< repeat pattern of code for the rest of the prompts, values, & custom iProperties >>>>
				End Select
			Next 'i
			'now try to delete this placed AutoCADBlock object from the sheet
			Try : oABC.Delete : Catch : End Try
		Next 'oABC
	Next 'oSheet
	'now that we have attempted to copy the needed data out,
	'and have attempted to delete all of the placed blocks that reference the definition,
	'we can now try to delete the block definition itself
	Try : oTargetACBD.Delete : Catch : End Try
	'you may need to update the drawing now
	If oDDoc.RequiresUpdate Then oDDoc.Update2(True)
	'you may want to save the drawing now, but maybe not, so I left this commented out
	'If oDDoc.Dirty Then oDDoc.Save2(False)
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 5 of 14

dypro
Advocate
Advocate

Hello @WCrihfield , thankyou for all the hard work.

There seems to be an error, when running the code, I think it's my mistake. 

There are two properties "FECHA CREACION" and "FECHA REVISION" that have to be in "date mode" but, when catching the data from the autocad block they are written as follows "06-08-2022" and that, before getting into the property I am guessing it has to be converted to something like "06/08/2022" . Can it be done?

dypro_0-1685694068980.png

Except for that, and that it doesn't delete the block, it works. I paste my actual rule here with all the lines so you have the full code. EDITED, check the bottom

 

 

Sub Main
	'make sure we are working with a drawing...if not let user know, and exit the rule
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
		MsgBox("Esta macro solo puede ser utilizada en un plano.", vbCritical, "")
		Exit Sub
	End If
	Dim oDDoc As DrawingDocument = ThisDoc.Document
	Dim oACBDs As AutoCADBlockDefinitions = oDDoc.AutoCADBlockDefinitions
	If oACBDs.Count = 0 Then Exit Sub 'none found in drawing, so exit the rule
	'this next variable will be used to store the block definition we are trying to find, when found
	Dim oTargetACBD As AutoCADBlockDefinition = Nothing
	'store the two possible names of the block definition we are looking for
	Dim PossibleBlockDefNames() As String = {"SH_CAR_S", "Copia de SH_CAR_S" }
	'loop through the AutoCADBlockDefinitions, to find the one we are after
	For Each oACBD As AutoCADBlockDefinition In oACBDs
		'if the block definition is not being referenced (no placed blocks for it), try to delete it
		'if an instance of it has not been placed, there will not be any values to get
		If oACBD.IsReferenced = False Then Try : oACBD.Delete : Catch : End Try
		'loop through the two possible names for the block definition
		For Each BlockDefName In PossibleBlockDefNames
			If oACBD.Name = BlockDefName Then
				oTargetACBD = oACBD
				Exit For 'exits this inner loop
			End If
		Next 'BlockDefName
		If oTargetACBD IsNot Nothing Then Exit For 'exit outer loop if target already found
	Next 'oACBD
	If IsNothing(oTargetACBD) Then Exit Sub 'the definition was not found, so exit rule
	
	'we must prepare the variables ahead of time, then this method fills in their values
	Dim oTags() As String = {}
	Dim oPrompts() As String = {}
	oTargetACBD.GetPromptTags(oTags, oPrompts)
	If oPrompts.Length = 0 Then Exit Sub 'the block definition does not have any prompts, so exit rule
	'these next two lines are simply for research & feedback, you can comment them out if you want
	'oTagx = InputListBox("", oTags, "", oTargetACBD.Name & " Tags", "List Of Tags")
	'oPromptx = InputListBox("", oPrompts, "", oTargetACBD.Name & " Prompts", "List Of Prompts")

	'get a reference to the drawing's 'Custom' iProperty set, for use later within the loop
	Dim oCProps As Inventor.PropertySet = oDDoc.PropertySets.Item(4)

	'now loop through the sheets to find placed blocks referencing the definition
	Dim oSheets As Inventor.Sheets = oDDoc.Sheets
	For Each oSheet As Inventor.Sheet In oSheets
		Dim oACBs As AutoCADBlocks = oSheet.AutoCADBlocks
		If oACBs.Count = 0 Then Continue For 'skip to next sheet if no blocks on this sheet
		For Each oABC As AutoCADBlock In oACBs
			'if the definition this block is referencing is not our 'target' one, then skip to next block
			If oABC.Definition IsNot oTargetACBD Then Continue For
			'again, we must prepare the variables first, then this method fills in their values
			Dim oPromptTags() As String = {}
			Dim oValues() As String = {}
			oABC.GetPromptTextValues(oPromptTags, oValues)
			If oPromptTags.Length = 0 Then Continue For 'there were no prompts, so skip to next
			'again, these next two lines are simply for research & feedback
			'oPromptTagx = InputListBox("", oPromptTags, "", oABC.Name & " PromptTags", "List Of PromptTags")
			'oValuex = InputListBox("", oValues, "", oABC.Name & " Values", "List Of Values")
			For i As Integer = 0 To UBound(oPromptTags)
				Dim sPromptTag As String = oPromptTags(i)
				Dim sValue As String = oValues(i)
				Dim oCProp As Inventor.Property = Nothing
				Select Case sPromptTag
					Case "SH_AFFAI"
						Try : oCProp = oCProps.Item("NUMERO INSTALACION")
						Catch : oCProp = oCProps.Add(sValue, "NUMERO INSTALACION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_PARTI"
						Try : oCProp = oCProps.Item("CODIGO DE PARTICION")
						Catch : oCProp = oCProps.Add(sValue, "CODIGO DE PARTICION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_MODUL"
						Try : oCProp = oCProps.Item("NUMERO MODULO")
						Catch : oCProp = oCProps.Add(sValue, "NUMERO MODULO") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_TECHN"
						Try : oCProp = oCProps.Item("CODIGO TECNICO")
						Catch : oCProp = oCProps.Add(sValue, "CODIGO TECNICO") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_T_D_D"
						Try : oCProp = oCProps.Item("TIPO DE PLANO")
						Catch : oCProp = oCProps.Add(sValue, "TIPO DE PLANO") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_N_O"
						Try : oCProp = oCProps.Item("NUMERO PLANO")
						Catch : oCProp = oCProps.Add(sValue, "NUMERO PLANO") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_CREVI"
						Try : oCProp = oCProps.Item("NUMERO REVISION")
						Catch : oCProp = oCProps.Add(sValue, "NUMERO REVISION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_N_D_C"
						Try : oCProp = oCProps.Item("NOMBRE DE CLIENTE")
						Catch : oCProp = oCProps.Add(sValue, "NOMBRE DE CLIENTE") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_TYP_I"
						Try : oCProp = oCProps.Item("TIPO DE INSTALACION")
						Catch : oCProp = oCProps.Add(sValue, "TIPO DE INSTALACION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_LIB_E"
						Try : oCProp = oCProps.Item("PRIMERA LINEA")
						Catch : oCProp = oCProps.Add(sValue, "PRIMERA LINEA") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_LIB_P"
						Try : oCProp = oCProps.Item("SEGUNDA LINEA")
						Catch : oCProp = oCProps.Add(sValue, "SEGUNDA LINEA") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_LIB_D"
						Try : oCProp = oCProps.Item("TERCERA LINEA")
						Catch : oCProp = oCProps.Add(sValue, "TERCERA LINEA") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_DESS"
						Try : oCProp = oCProps.Item("DISEÑADOR")
						Catch : oCProp = oCProps.Add(sValue, "DISEÑADOR") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_DATE_DESS"
						Try : oCProp = oCProps.Item("FECHA CREACION")
						Catch : oCProp = oCProps.Add(sValue, "FECHA CREACION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_VERIF"
						Try : oCProp = oCProps.Item("VERIFICADOR")
						Catch : oCProp = oCProps.Add(sValue, "VERIFICADOR") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_TREVI"
						Try : oCProp = oCProps.Item("REVISION")
						Catch : oCProp = oCProps.Add(sValue, "REVISION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_TYP_MODIF"
						Try : oCProp = oCProps.Item("MOTIVO REVISION")
						Catch : oCProp = oCProps.Add(sValue, "MOTIVO REVISION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_NAME_MODIFIER"
						Try : oCProp = oCProps.Item("NOMBRE MODIFICADOR")
						Catch : oCProp = oCProps.Add(sValue, "NOMBRE MODIFICADOR") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_DATE_MODIF"
						Try : oCProp = oCProps.Item("FECHA REVISION")
						Catch : oCProp = oCProps.Add(sValue, "FECHA REVISION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
					Case "SH_NAME_CHECK"
						Try : oCProp = oCProps.Item("VERIFICADOR REVISION")
						Catch : oCProp = oCProps.Add(sValue, "VERIFICADOR REVISION") : End Try
						If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
						'<<<< repeat pattern of code for the rest of the prompts, values, & custom iProperties >>>>
				End Select
			Next 'i
			'now try to delete this placed AutoCADBlock object from the sheet
			Try : oABC.Delete : Catch : End Try
		Next 'oABC
	Next 'oSheet
	'now that we have attempted to copy the needed data out,
	'and have attempted to delete all of the placed blocks that reference the definition,
	'we can now try to delete the block definition itself
	Try : oTargetACBD.Delete : Catch : End Try
	'you may need to update the drawing now
	If oDDoc.RequiresUpdate Then oDDoc.Update2(True)
	'you may want to save the drawing now, but maybe not, so I left this commented out
	'If oDDoc.Dirty Then oDDoc.Save2(False)
End Sub

 

 

For now I am not saving, but yes, probably I will uncomment the line after testing. Or maybe add a question to the user about saving or not.

BTW: Is there also a way to change the color of the sheet to 100,100,100? 

EDIT: ok, @WCrihfield , I've been working on why it does not work the delete thingy, and I have discovered that it DOES delete the block, but only when there is no error. For some reason, when I delete all date iproperties that already where into the drawing it does work.
I have been testing it, the code creates the date Iproperty as "text" (they should be "date") so, if I delete the Iproperties that already where in the drawing and had the "date" parameter on, It creates the iproperties with the "text" parameter on, it does not show an error, and it deletes the block. So i'm guessing that we just have to modify that properties so they have the "date" thing on, and something that prior to getting the parameter into the iproperty changes every "-" for a "/" ..... im I right?

0 Likes
Message 6 of 14

WCrihfield
Mentor
Mentor

Hi @dypro.  The 'data type' of any 'custom' iProperty is simply set by what 'data type' you set as its value.  And to change the 'data type' of an existing iProperty's value, you can simply set a new value to it that is pre-defined as the data type you want it to be.  In this case, since we are copying data from an AutoCADBlock, each value we get from that source is already a String, but if you know which specific ones need to be understood as another data type, we can use 'data type conversion' techniques to accomplish that.  I will post a few related links below that will be informative in this matter.  You should be able to use something like 'CDate(sStringDateData)' to convert a String which represents Date type data into a Date type Data, either before we set it as the value of the iProperty, or as we are setting it as the value of the iProperty.  How the Date data is formatted is another matter.  That is usually handled automatically, and has something to do with your local 'culture' settings in your computer.  But you can use certain methods to customize how Date type data is formatted, if it is still a problem after you try the data type conversion technique mentioned above.

https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/functions/type-conversion-f... 

https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/data-types/date-data-type 

https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings 

Here is an example you can try out, within your code.

Case "SH_DATE_DESS"
	Dim dCreationDate As Date = CDate(sValue)
	Try : oCProp = oCProps.Item("FECHA CREACION")
	Catch : oCProp = oCProps.Add(dCreationDate, "FECHA CREACION") : End Try
	If oCProp.Value <> dCreationDate Then Try : oCProp.Value = dCreationDate : Catch : End Try

 

And you can change the color of a drawing sheet, but I don't think you can change them individually.  The setting is in the 'Document Settings', so that setting will effect all sheets, not just one sheet.  That setting can be reached by code too, if you need to.  (DrawingDocument.SheetSettings & SheetSettings.SheetColor )

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 7 of 14

dypro
Advocate
Advocate

hello @WCrihfield 

I tried the code, but just to get an error again.
I copy paste it here:

System.InvalidCastException: La conversión de la cadena "" en el tipo 'Date' no es válida.
en Microsoft.VisualBasic.CompilerServices.Conversions.ToDate(String Value)
en ThisRule.Main()
en Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
en iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

First line means "the conversion of the string "" into 'Date' type is not valid"

 

I think that what is failing is that in the autocad block the "SH_DATE_MODIF" may have a date, but often will be empty, and the 'date' type cannot handle the "" value?

I tried:

Case "SH_DATE_MODIF"
						Try : oCProp = oCProps.Item("FECHA REVISION")
						If oCProp = "" Then 
							Dim dModifDate As String = CDate(sValue)
						Else
							Dim dModifDate As Date = CDate(sValue)
						End If
						Catch : oCProp = oCProps.Add(dmodifdate, "FECHA REVISION") : End Try
						If oCProp.Value <> dModifDate Then Try : oCProp.Value = dModifDate : Catch : End Try

but something must be wrong with the syntax or something because it gives an error as well:

Compilation errors in the rule

the variable  'dModifDate' hides a variable in an inclusion block

or something like that (it's in spanish so I tried to translate it)

 

 

On the other hand, I did manage to make the sheets change color.

 

PD: I just noticed as well the need to delete a block witch may be named "MARCO2000" or "Copia de MARCO2000". I tried to replicate your code but I could not make it work.

0 Likes
Message 8 of 14

WCrihfield
Mentor
Mentor

Hi @dypro.  When the Value of the AutoCADBlock's attribute is empty, do you still want to create a custom iProperty for that attribute, even though it could not be assigned a value?  If you would like to simply skip over any attributes that do not have a value, we could check for that just before the Select Case block of code starts, like this:

For i As Integer = 0 To UBound(oPromptTags)
	Dim sPromptTag As String = oPromptTags(i)
	Dim sValue As String = oValues(i)
	If sValue = "" Then Continue For

...that last line would be the only new line needed to make that happen.

However, if you do want to still create the custom iProperty for that attribute, even if its value is empty, then there are some options about how to proceed.  Obviously the first thing we would need to check is 'sValue', to see if it is either empty, or if its contents are convertable to the Date data type.  I wrote out some code, as an alternate example, to help avoid these problems, but I'm sure this code could have been written more efficiently.  I was just in a hurry because I've got a lot of other stuff going on at the moment.  You will notice an additional check in there (IsDate), which can be used to determine if the provided data can be understood as, or converted to, the Date type.  Also, in order to keep the code condensed, I am using a lot of ':' (colon) symbols in there to combine multiple lines of code into fewer lines, but feel free to expand that stuff out if you want to.  And if you need more feedback in order to be able to tell exactly what all is happening, feel free to throw some Logger.Info("some information") type lines in there.  I often use the Logger a lot in new codes, then eliminate them later, once I'm comfortable doing so.

Case "SH_DATE_MODIF"
	Dim bFoundRev As Boolean = False
	Dim dModifDate As Date
	Try : oCProp = oCProps.Item("FECHA REVISION") : bFoundRev = True : Catch : End Try
	If IsNothing(oCProp) Then
		If sValue = "" OrElse IsDate(sValue) = False Then
			Try : oCProp = oCProps.Add(sValue, "FECHA REVISION") : Catch : End Try
		ElseIf sValue <> "" AndAlso IsDate(sValue) = True Then
			Try : dModifDate = Convert.ToDateTime(sValue) : Catch : End Try
			Try : oCProp = oCProps.Add(dModifDate, "FECHA REVISION") : Catch : End Try
		End If
	End If
	If bFoundRev = True Then
		If sValue = "" OrElse IsDate(sValue) = False Then
			If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
		ElseIf sValue <> "" AndAlso IsDate(sValue) = True Then
			Try : dModifDate = Convert.ToDateTime(sValue) : Catch : End Try
			If oCProp.Value <> dModifDate Then Try : oCProp.Value = dModifDate : Catch : End Try
		End If
	End If

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 9 of 14

dypro
Advocate
Advocate

Hello again @WCrihfield 

I do want the iproperty to be created even if the field has nothing (it will probably be filled eventually)

For some reason the same error keeps popping up. I'm not sure anymore about what is happening, so I tried to msgbox everything (I tried with logger.info as you suggested, but It gets to msgbox 13 and then it just sais "some info" I've been searching trought the internet  and read about the levels of info, but I don't really get how to use it well)

For context, the file in wich this is being tested right now has a SH_DATE_MODIF value of "",  and a pre-existing "FECHA REVISION" in 'Date' mode

 

					Case "SH_DATE_MODIF"
						Dim bFoundRev As Boolean = False :MsgBox("1")
						Dim dModifDate As Date : MsgBox("2")
						Try : oCProp = oCProps.Item("FECHA REVISION") : bFoundRev = True : Catch : End Try : MsgBox("3")
						If IsNothing(oCProp) Then : MsgBox("4")
							If sValue = "" OrElse IsDate(sValue) = False Then : MsgBox("5")
								Try : oCProp = oCProps.Add(sValue, "FECHA REVISION") : Catch : End Try : MsgBox("6")
							ElseIf sValue <> "" AndAlso IsDate(sValue) = True Then : MsgBox("7")
								Try : dModifDate = Convert.ToDateTime(sValue) : Catch : End Try : MsgBox("8")
								Try : oCProp = oCProps.Add(dModifDate, "FECHA REVISION") : Catch : End Try : MsgBox("9")
							End If : MsgBox("10")
						End If : MsgBox("11")
						If bFoundRev = True Then : MsgBox("12")
							If sValue = "" OrElse IsDate(sValue) = False Then : MsgBox("13")
								If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try : MsgBox("14")
							ElseIf sValue <> "" AndAlso IsDate(sValue) = True Then : MsgBox("15")
								Try : dModifDate = Convert.ToDateTime(sValue) : Catch : End Try : MsgBox("16")
								If oCProp.Value <> dModifDate Then Try : oCProp.Value = dModifDate : Catch : End Try : MsgBox("17")
							End If : MsgBox("18")
						End If : MsgBox("19")

 

 

The results I get are:

1
2
3
11
12
13
error

dypro_0-1686034571616.png

dypro_1-1686034617260.png

Not sure if this will help you figure out what's wrong, but I hope so.

If I comment out this case, the code seems to work so the error must be in there somewhere.

And don't worry @WCrihfield , I was actually kind of enjoying this, cause I'm learning and being able to do certain things with the ilogic has proven trully useful to me, but if you are in a hurry you don't need to clarify everything, I will eventually figure out myself what the code does 

0 Likes
Message 10 of 14

dypro
Advocate
Advocate
BUMP
0 Likes
Message 11 of 14

dypro
Advocate
Advocate

hello everyone,  

I don't get what is wrong with this code, I have tried everything it ocurred to me...and nothing works.

I have tried the code from @WCrihfield but it just keeps prompting the error. 

I tried to add ifs before, and to change every single line to something else (with my really poor ilogic knowledge).

Right now I'm just trying to skip the case if there is not a date in the parameter of the autocad block but for some reason it doesn't work. (It really is not what I wanted to do, but right now, i'll be ok with anything)

					Case "SH_DATE_MODIF"
						Dim dRevDate As Date
						Dim cero As Integer
						cero = "0"
							Try : oCProp.value("FECHA REVISION") = cero : Catch : End Try
							Try : oCProp = oCProps.Item("FECHA REVISION") : Catch : End Try
								If oCProp.Value = cero
									GoTo siguiente
								Else
									Try : oCProp = oCProps.Item("FECHA REVISION") 
									Catch : oCProp = oCProps.Add(sValue , "FECHA REVISION") : End Try 
									If oCProp.Value <> sValue Then Try : oCProp.Value = sValue : Catch : End Try
								End If
							 
							siguiente :
							

 It prompts "reference to an object not established as instance of an object" 

I tried to put it as an string as well but nothing

It must be something really simple, but I don't see the problem

0 Likes
Message 12 of 14

WCrihfield
Mentor
Mentor

Hi @dypro.  I finally revisited this again today, and I tried something a bit different.  The big problem with trying to convert an unknown String into a true Date type, is that you sort of need to know what format the String is already in ahead of time.  If you do not know how the String is laid out or formatted, it is a a guessing game, and the data type conversion might either fail, come out not correct/ not accurate.  In this version, I tacked the possibility of the sValue being either empty, or simply not convertable to a Date, at the top of the loop.  Then I created the 'oDate' variable as a Date data type, and since a variable of that type can not have its value nullified, I set its initial value to its minimum value (beginning of the day, year 0000).  Then I try to convert the sValue String type data to a Date to set as the value of that oDate variable, using the local 'culture' info from your computer when you run the code.  I can only hope that will be accurate.  Then I simply try to use that oDate variable down within those two Case statements below that need a Date type value.  Either way, it should set a value as a Date, but the date may be wrong if it had trouble converting.

 

I attached a text file to this response containing the modified code.  I basically copied the last full code from above in this post, then modified it as seemed logical to me right now.  I hope this works better for you.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 13 of 14

dypro
Advocate
Advocate

Hello again @WCrihfield thank you for keep trying.

Now it does work when there is no revision date and it doesn't prompt the error anymore, but it prompts a revision date...  

 

06/08/2022 is the creation date, so the revision date would be better empty than that, it only will lead to error.

dypro_0-1686554612337.png

I'm guessing that is the "minimum value" you talk about... there is a way to make it just not appear in that case?

 

When you use the 'date' in the iproperties there is a box you can uncheck to make it go to "".

Not sure how difficult is to replicate that with ilogic. Maybe something like, "if the date going to be displayed is nothing uncheck that box" or "if your date is prior to the 1900, uncheck the box" ?

The normal thing to do would be:

dypro_3-1686556668462.pngdypro_4-1686556692468.png

uncheck the box

dypro_5-1686556712501.png

hit modify

dypro_6-1686556849433.png

the iproperty does exist but has been emptyed so just hit apply or accept and whe have it.

 

Again, not sure how difficult is to achieve this in ilogic

 

0 Likes
Message 14 of 14

dypro
Advocate
Advocate

By the way @WCrihfield , just saw your PM, I don't usually check it.

If you don't have the software to test it, I will happily run the test code for you in that specific case scenario if you want to satisfy your curiosity.

0 Likes