P&ID’s - TEC / CADCollege AutoCAD en Inventor, · PDF fileeen tekensysteem dat in de...
Transcript of P&ID’s - TEC / CADCollege AutoCAD en Inventor, · PDF fileeen tekensysteem dat in de...
P&ID’s
Gestructureerd EN simpel P&ID's tekenen.
50/25MM-03425
M
FUNCTIE001
40/2
5MM
-011
2525
/40
V-002
40
2525
50
150
15/2
5MM
-016
15
MM
25
-015
40
MM-032
15
001
1510
/15
MM
-033
1515
/10
N2???
150 15040
002
MM-030
25
MM
-031
40/2
5
E-001A
E-001B
20
20
20
20
50
E-002
20
20
25/4
0
V-003
20040 100 100 40
40/1
5
MM
-041
15
40/2
5
MM
-040
2525
/40
40
40/25
MM-042
25
MM
-014
2520
/25
MM
-012
25
25
25
003
MM-027 50/25
MM
-024
20
20/40
MM-028
40 40/25
20/40
MM-029
40 40/25
002
GLA
SE
MA
ILLE
ST1
15/25
MM
-010
15M
M-0
0915
IA2
TEK. DI-01-HPE-00215/25
DS
WATER AFVOER
CO1
TEK. DI-01-HST-001 MM-03715
MM-038
15MM-039
15
VAC
MM
-017
25
MM
-019
25
MM
-020
25
15/2
5
MM-018
4050/40 40/25
RVS
RVS
RVS
GLA
S
VS2
DI-01-HAF-002
WC1
WC2
001
SET AT?? barg
40
25
MM-026
25
MM-025
25
MM-035
25
MM
-013
25
MM
-054
20/4
0
20/4
0
101
H
RVSGLAS RVS
XV-???
??XV-???
??
XV-?
??
??
DW
TEK. DI-01-HPE-002
MM-038
15MM-038
15
80/150
SYN
THES
ER
UIM
TE
BU
ITE
N
Naam: Hans Boer
Bedrijf: IV-Industrie B.V.
Studierichting: ACE System Manager
Datum: 18-december-2009
Voorwoord Het HBO traject wilde ik al volgen sinds het einde van de jaren 90. Ik werkte toen
bij een chemisch bedrijf waar ik in 1992 heb leren programmeren in LISP.
Eind jaren 90 begon de periode waarin tekenen niet meer mijn kern taak was.
Ik werd jr. engineer E&I, iets wat voor mij interessant was omdat het beter werd
gewaardeerd, zowel financieel als het persoonlijk.
In die tijd bleek mijn ervaring met AutoCad tevens mijn zwakke punt te zijn. Het
leverde juist een afwijzing op om het HBO traject bij TEC te mogen volgen.
Mijn kennis, die echter hoog gewaardeerd werd, vond men meer dan voldoende.
Na de overstap naar mijn huidige werkgever ben ik tussen 2007 en 2009
uitgegroeid tot “Mister P&ID”. Ooit ben ik begonnen als designer maar nu weer
werkzaam als tekenaar waar ik nog steeds een zwak voor heb. Mijn motivatie om
toch weer het HBO traject te gaan volgen komt voort uit de liefde voor het vak
tekenen en het ontbreken van erkenning als AutoCad tekenaar. Die erkenning zie
ik met de titel ACE System manager binnen handbereik liggen en is wellicht het
middel om meer invloed te krijgen op gebied van efficiëntie binnen grote projecten
en de diverse tekenkamers.
Het HBO traject bij TEC heeft mijn werkplezier vanaf dag één enorm verbeterd. De
opgedane ervaring tijdens dit project wordt gaande weg in het verslag steeds meer
zichtbaar. Redenen genoeg om deze gelegenheid te gebruiken de volgende
mensen te bedanken:
Leonie, die mij als eerste via de telefoon heeft binnen geloodst bij TEC.
Ronald, voor het wegnemen van technische drempels en de laatste duw richting
examen, dat ik eigenlijk over de jaarwisseling wilde tillen.
Paul, die mij met beide benen op de grond zette op gebied van standaard
AutoCad. Waarmee ineens heel veel mogelijk bleek.
Tenslotte Yvonne, Mariska en Jeanine die mijn aandacht weer hard nodig hebben
na al het geëxperimenteer met VBA.
2
Samenvatting Dit verslag beschrijft:
• Een set Visual Basic programma’s waarmee heel snel met blokken kan worden
gewerkt.
• Een set dynamische blokken. Dit is een basis set met symbolen voor Piping en
Instrumentatie. De apparaten symbolen zijn hierin niet aangemaakt (behalve
de pompen) omdat ze door de Visual Basic programma’s niet interessant zijn.
• Een programma waarmee leidingen kunnen worden gegroepeerd. Een handig
hulpmiddel om snel te kunnen zien welke onderdelen bij een bepaald
leidingnummer horen.
3
Inhoud Voorwoord .............................................................................................................. 2
Samenvatting ......................................................................................................... 3
Inhoud .................................................................................................................... 4
1 Inleiding........................................................................................................... 5
2 Bedrijfsomstandigheden.................................................................................. 6
2.1 Organisatie Vestiging Haarlem ................................................................ 7 2.1.1 Huidige rol..................................................................................................................... 7 2.1.2 Toekomstige rol als ACE system manager .................................................................. 7
2.2 Beschrijving PID tekenwerk ..................................................................... 8 2.3 Tekenwerk voor nieuwbouw..................................................................... 8 2.4 Tekenwerk voor bestaande installaties .................................................... 8
2.4.1 Aanpassing van een bestaande procesinstallatie ....................................................... 8 2.4.2 Verwerking van de actuele situatie op PID................................................................... 9 2.4.3 Volledig uittekenen van procesinstallaties.................................................................... 9
3 Probleem stelling........................................................................................... 10
4 Doelstelling.................................................................................................... 11
4.1 Tijdwinst ................................................................................................. 11 4.2 Kwaliteit van PID’s ................................................................................. 11 4.3 Subdoel.................................................................................................. 12
5 Probleem aanpak .......................................................................................... 13
6 Functies van de tekenhulpmiddelen.............................................................. 15
6.1 Werken met blokken .............................................................................. 15 6.1.1 Plaatsen van een blok ................................................................................................ 16 6.1.2 Kopiëren van een blok................................................................................................ 17 6.1.3 Verplaatsen van een blok ........................................................................................... 17 6.1.4 Verwijderen van een blok ........................................................................................... 17 6.1.5 Het gedrag van blokken.............................................................................................. 17
6.2 Dynamische blokken .............................................................................. 22 6.2.1 Blokparameters voor de gebruiker ............................................................................. 22 6.2.2 Blokparameters voor VBA .......................................................................................... 23
6.3 Leidingen ............................................................................................... 24 6.3.1 Toekenning van leidingnummers................................................................................ 25 6.3.2 Tonen van een leiding ................................................................................................ 25 6.3.3 Toevoegen en verwijderen van objecten.................................................................... 25 6.3.4 Aanbrengen van leiding labels ................................................................................... 25 6.3.5 Data export ................................................................................................................. 26
7 Uitleg van programma’s ................................................................................ 27
7.1 Het plaatsen van een blok...................................................................... 28 7.1.1 Het positioneren van een blok .................................................................................... 29
7.2 Xdata toevoegen.................................................................................... 38 7.2.1 Leidingnummers toegvoegen ..................................................................................... 39 7.2.2 Blokparameters toevoegen......................................................................................... 41
8 Conclusie ...................................................................................................... 42
9 Nawoord........................................................................................................ 43
4
1 Inleiding Het tekenen van P&ID’s kan sneller en beter. Waarom en hoe kan het sneller en
beter. Op deze vraag hoop ik in komende hoofdstukken het passende antwoord te
geven.
De officiële betekenis van P&ID is: Piping & Instrument Diagram.
In de praktijk is dit een schematische weergave van een procesinstallatie.
Bij veel bedrijven wordt P&ID ook aangeduid met de afkorting PID. In dit verslag
heb ik gekozen voor de afkorting PID.
In de meeste productie bedrijven is het PID het belangrijkste technische
document. Alle technische discussies m.b.t. proces optimalisatie, veiligheid en
milieu, onderhoud en verplichte periodieke inspecties beginnen bij de PID.
Het is meestal het document met de hoogste informatie dichtheid. Uit een goed
opgezette PID kan een procestechnoloog vrij gedetailleerd de werking van een
procesinstallatie achterhalen. Vandaar dat sommige bedrijven nogal terughoudend
zijn met de uitgifte van PID’s aan derden. Voor IV-Industrie begint elk project aan
een procesinstallatie met het bestuderen van de PID’s. In die zeldzame gevallen
waarin deze documenten ontbreken zullen ze alsnog moeten worden gemaakt.
Ook de overheid en met name de arbeidsinspectie hecht grote waarde aan de
betrouwbaarheid van de PID’s. Er worden door de arbeidsinspectie zelfs
steekproeven genomen ter controle van de actuele status. Voortvloeiend uit zo’n
steekproef is dit jaar nog tekenwerk verricht door IV-Industrie.
De tekenhulpmiddelen die in dit verslag worden behandeld vormen de aanzet tot
een tekensysteem dat in de toekomst een alternatief kan worden voor AutoCad
P&ID. Na dit afstudeerproject zullen steeds meer functies worden toegevoegd.
In dit verslag zo veel mogelijk gestreefd naar het gebruik van Nederlandse termen.
In sommige gevallen is ter verduidelijking de engelse term tussen haken vermeld.
Uiteraard is niet alles even makkelijk in het nederlands uit te drukken. Typische
AutoCad termen als “bylayer” of “Xdata” zijn niet vertaald, maar in hun
oorspronkelijke benaming tussen aanhalingstekens weergegeven.
Ook VBA codering wordt bij de uitleg van de programma’s niet vertaald.
5
2 Bedrijfsomstandigheden Dit afstudeerproject is gemaakt voor IV-Industrie B.V. (voormalig TripleM b.v.)
IV-Industrie is een onderdeel van IV-Groep.
IV-Groep is werkzaam in de markten:
• Gebouwen & Constructies
• Industrie & Energie
• Infrastructuur & Havens
• Maritiem
• Olie & Gas
• Water
IV-Industrie is werkzaam in de markt Industrie & Energie en is gevestigd in
Haarlem, Arnhem en Papendrecht.
De overige bedrijven die vallen onder IV-Groep zijn:
• IV-Consult b.v.
• IV-Infra b.v.
• IV-Oil & Gas b.v.
• IV-Water b.v.
• Iv-Caribbean n.v. (76%)
• Nevesbu b.v. (50%)
• IV-Software b.v.
• Muzada b.v.
De deelmarkten van IV-Industrie zijn:
• Farmaceutische industrie
• Voedingsmiddelen industrie
• Chemische industrie
• Basis industrie
• Energieopwekking en transport
• Transport & handling systems
6
Voor overige informatie m.b.t de organisatie verwijs ik u naar de website van IV-
Groep: www.iv-groep.nl
Binnen de IV-Industrie vestiging in Haarlem waar veelvuldig werk wordt verricht
voor de chemische en farmaceutische industrie, is PID’s tekenen een belangrijke
vakspecialiteit. Begrip van de toegepaste tekennormen, procestechnisch inzicht en
regeltechnisch inzicht is nodig om de werking van een procesinstallatie duidelijk
over te brengen op een PID.
2.1 Organisatie Vestiging Haarlem
De vestiging Haarlem heeft twee pijlers
• Engineering
• Project management
Engineering is verdeeld in
• Wtb
• Farma
• EI&A
• Piping
Mijn functie is E&I designer en valt onder EI&A.
2.1.1 Huidige rol
In mijn huidige rol wordt ik benaderd als designer. In de praktijk betekent dit
uitvoeren wat door de engineers wordt opgedragen. Dit betekent dus dat je pas in
het eind stadium van een project invloed kunt uitoefenen. Ook op zaken waarvan
ik veel meer kennis heb dan de engineers. Hiermee bedoel ik het efficiënt
tekenen, efficiënt omgaan met data stromen van tekening naar database en vice-
versa. Het beheer van AutoCad tekeningen over een heel project.
2.1.2 Toekomstige rol als ACE system manager
Een titel als ACE system manager kan een handvat zijn om in een vroeger
stadium verbeteringen door te voeren op meerere terreinen.
7
Dus ook buiten het terrein van de PID’s en elektrische schema’s uit mijn eigen
vakgebied. De uitdaging wordt om meerdere vakdisciplines te laten afwijken van
de platgetreden paden uit het verleden.
2.2 Beschrijving PID tekenwerk
Al dat tekenwerk binnen IV-Industrie is globaal in twee categorieën te verdelen:
• Tekenwerk voor nieuwbouw.
• Tekenwerk voor bestaande installaties.
2.3 Tekenwerk voor nieuwbouw
Een nieuwe procesinstallatie wordt door procestechnologen in een proces-
flowschema beschreven dat in een latere fase gedetailleerd wordt uitgewerkt in
meerdere PID’s. Dit uitwerken wordt gedaan door ervaren vaktekenaars.
Bij kleine installaties komt het voor dat PID’s direct worden getekend door de
procestechnoloog in AutoCad. Deze PID’s zijn meestal als schetsmatig van opzet,
dus zonder gebruik van belangrijke basisfuncties, of ondeskundig gebruik van de
basisfuncties. Bijvoorbeeld:
• Blokken met platte tekst i.p.v. attributen.
• Blokken die worden gedefinieerd voor meerdere standen (horizontaal,
vertikaal en gespiegeld).
• Helemaal geen blokken maar alleen losse entiteiten.
• Tekenen zonder raster.
2.4 Tekenwerk voor bestaande installaties
Het PID tekenwerk aan bestaande installaties is als volgt te verdelen:
• Aanpassing van een bestaande procesinstallatie.
• Verwerking van de actuele situatie
• Volledig uittekenen van procesinstallaties
2.4.1 Aanpassing van een bestaande procesinstallatie
Op basis van bestaande PID’s worden project PID’s gemaakt waarop de
modificaties zijn aangegeven. Na afloop van het project, als alle modificatie
gerealiseerd zijn, moeten de project PID’s worden overgedragen aan de klant.
8
Mits modificaties conform PID uitgevoerd zijn, mag worden aangenomen dat de
project PID’s na overdracht de actuele situatie weergeven.
Meestal krijgen de PID’s voor de overdracht nog een laatste veldcontrole.
2.4.2 Verwerking van de actuele situatie op PID
Verwerking van de actuele situatie op PID. Dit wordt in populaire bewoordingen de
as built status genoemd. Bij verschillende bedrijven, waaronder ook klanten van IV
is de actuele situatie niet correct bijgehouden op PID. Vaak ontstaat dit na
periodieke fabriek stops voor grootschalig onderhoud. Opmerkingen op PID die
door de klant zijn aangegeven moeten dan worden verwerkt.
2.4.3 Volledig uittekenen van procesinstallaties.
Bij enkele bedrijven komt het nog voor dat PID’s gedeeltelijk of volledig ontbreken.
IV-Industrie krijgt dan de opdracht de bestaande situatie te verwerken op PID.
Ter plaatse wordt de actuele situatie handmatig geschetst, waarna deze op
kantoor wordt uitgewerkt in AutoCad.
Hierin zijn ook weer twee situaties te onderscheiden:
Tekenvoorschriften en legenda wordt door de opdrachtgever verstrekt.
IV-Industrie krijgt alle vrijheid in het samenstellen van een legenda en de wijze
waarop wordt getekend.
9
3 Probleem stelling Samengevat kan het probleem als volgt worden omschreven:
Bij het tekenen van PID’s gaat veel tijd verloren en is de kwaliteit te vaak
onacceptabel. De oorzaak hiervan is:
• PID schetsen welke zijn gemaakt door onervaren tekenaars die een eigen
leven gaan leiden en uiteindelijk worden verheven tot officieel document, of
vanwege gebrekkige kwaliteit moeten worden overgetekend door een
vaktekenaar.
• Onwetendheid m.b.t. de aanwezige vakkennis binnen de vestiging in
Haarlem.
• Het ontbreken van dynamische symbolen en eenvoudige
tekenhulpmiddelen.
De eerste twee problemen zijn van organisatorische aard en daarom in principe op
organisatorisch niveau structureel oplosbaar.
Een ander neveneffect van kwalitatief slechte PID’s is het ontbreken van structuur
Daardoor is het niet meer mogelijk om diverse lijsten met onderdelen de
genereren uit de PID’s.
Dergelijke lijsten worden dus vaak met de hand in Excel ingevoerd.
10
4 Doelstelling Doel: Tijdwinst en kwaliteitsverbetering bij de productie van PID’s.
Subdoel: Het bovenstaande doel ook kunnen vertalen naar andere toepassingen.
4.1 Tijdwinst
Tijdwinst kan rechtstreeks worden verkregen door sneller tekenen via handige
hulpmiddelen.
Indirect door betere kwaliteit. Dus minder handelingen achteraf door een
vaktekenaar die schetsen moet bijwerken of overtekenen. Ook de mogelijkheid tot
het genereren van lijsten draagt bij aan tijdwinst.
4.2 Kwaliteit van PID’s
Wat is bepalend voor een goede kwaliteit van PID’s?
• De leesbaarheid. Bijvoorbeeld het streven alle stromen van links naar rechts
in een zo recht mogelijke lijn weer te geven. Zoveel als mogelijk kruisende
lijnen en onnodige bochten vermijden.
• Logische indeling. Een duidelijke scheiding van proces en hulpsystemen.
Een duidelijke weergave van de regelkringen waaruit de werking makkelijk is
te herleiden.
• De mogelijkheid lijst informatie te genereren. Zoals leiding, appendage,
instrument en apparaten lijsten. Of zelfs een overzicht van alle onderdelen
die vallen onder één leidingnummer. Een goed hulpmiddel voor het maken
van begrotingen.
• Eenvoud. Bijvoorbeeld zorgvuldig gebruik van lagen. Dus lagen alleen
gebruiken om specifieke informatie wel/niet zichtbaar te maken. Dus geen
gebruik meer van lagen om tekentechnische redenen en voor
vereenvoudiging van data-extractie. Deze werkwijzen zijn door huidige stand
der techniek achterhaald.
11
4.3 Subdoel
PID’s vertonen veel overeenkomsten met o.a. elektrische, pneumatische en
hydraulische schema’s. Als subdoel is het interessant om problemen over
meerdere vakdisciplines op te lossen. In hoeverre zijn concepten die voor PID’s
zijn ontwikkeld, toepasbaar voor andere vakdisciplines? Dit kan een bepalende
factor zijn om bepaalde toepassingen wel of niet verder uit te ontwikkelen.
12
5 Probleem aanpak Er zijn twee mogelijke oplossingen:
• De aanschaf van een Applicatie zoals AutoCad PID of Autoplant.
• Het aanmaken van handige tekenhulpmiddelen.
Er is gekozen voor handige tekenhulpmiddelen
Met handige en vooral eenvoudige tekenhulpmiddelen is wel degelijk winst te
behalen. Zeker wanneer onervaren tekenaars deze hulpmiddelen gaan gebruiken.
Dit project beschrijft drie tekenhulpmiddelen.
1. Tekenhulp voor het werken met blokken
2. Gebruik van dynamische blokken
3. Het groeperen van leiding onderdelen en het plaatsen van leidingnummers.
Een alternatief dat in de vestiging van Haarlem is besproken is AutoCad P&ID.
Voordelen:
• Het ideale gereedschap voor het ontwerp van nieuwe procesinstallaties.
• Relatief snel aan te leren door vaktekenaars.
• Zeer ruim toepasbaar.
• Koppelbaar met databases.
Nadelen:
• AutoCad PID genereert nieuwe entiteiten die in standaard AutoCad niet
voorkomen zoals “Sline”. Bewerken van dergelijke tekeningen met
standaard AutoCad is wel mogelijk maar veel intelligentie zal verloren gaan.
• Hoge opstartkosten door cursussen.
Waarom toch zelf gemaakte tekentools?
AutoCad P&ID is bij IV-Industrie op dit moment geen optie. Het aantal opdrachten
is te klein om deze software aan te schaffen en mensen daarvoor op te leiden. De
praktijk leert dat slechts het volgen van een cursus niet voldoende is om de
software efficiënt te gebruiken.
13
Om via standaard AutoCad te kunnen concurreren met AutoCad P&ID zal een
systeem moeten worden bedacht waarbij de gebruiker een korte leerperiode nodig
heeft en toch kinderlijk eenvoudig leidingen tekent en symbolen plaatst.
14
6 Functies van de tekenhulpmiddelen De tekenhulpmiddelen die zijn genoemd bij de probleem aanpak worden in dit
hoofdstuk per functie beschreven. Als eerste wordt ingegaan op het werken met
blokken. Daarop aansluitend komen de dynamische blokken aan bod. Als laatste
wordt het groeperen van leidingen behandeld.
Voor het werken met blokken en groeperen van leidingen zijn programma’s
geschreven in Visual Basic for Applications. In algemeen taalgebruik bekend
onder de afkorting VBA.
Voor de aanmaak van dynamische symbolen is gebruik gemaakt van standaard
AutoCad functies. Echter het gedrag van deze blokken kan achteraf worden
beïnvloed door de toevoeging specifieke eigenschappen. Hierbij is gebruik
gemaakt van de voorziening in AutoCad om extra informatie aan een object toe te
voegen. Deze extra informatie is onzichtbaar en wordt in AutoCad aangeduid met
de term “Xdata”. Met een VBA programma kan “Xdata” tijdens het tekenen worden
toegevoegd en gewijzigd. Meer uitleg hierover volgt in paragraaf 6.1.
De dynamische blokken zijn verwerkt in “toolpalettes”, en de overige
tekenhulpmiddelen worden expliciet als commando aangeroepen.
6.1 Werken met blokken
Voor het werken met blokken zijn VBA programma’s voor de volgende basis
handelingen:
1. Plaatsen van een blok
2. kopiëren van een blok
3. verplaatsen van een blok
4. verwijderen van een blok
15
6.1.1 Plaatsen van een blok
Wanneer met standaard AutoCad een blok geplaatst moet worden op een
verticale lijn zal een tekenaar minimaal de volgende handelingen nodig hebben:
1. commando “Insert”
2. Invoer van de blok naam
3. punt aanwijzen
4. rotatie hoek opgeven
5. commando “Break”
6. lijn selecteren
7. Optie “F” voor het aanwijzen van twee punten
8. eerste punt aanwijzen
9. tweede punt aanwijzen
Het plaatsen van een blok kan duidelijk sneller met het VBA programma.
De volgende handelingen zijn nodig:
1. Selecteer een symbool in het “toolpalette”
2. Wijs de positie aan op een lijn
Het geselecteerde blok wordt door een VBA programma in de juiste positie op de
lijn geplaatst waarna de lijn onder het blok automatisch wordt gebroken. Wanneer
de lijn vertikaal is wordt het blok onder een hoek van 90° geplaatst. Niet elk blok
zal zich zo gedragen zoals hier is beschreven. Het programmadeel dat het blok
positioneert kan aan het blok herkennen hoe het moet worden geplaatst. Dit
programmadeel wordt ook gebruikt voor het kopieren en verplaatsen van blokken.
Meer uitleg over het positioneren van blokken volgt verderop in dit hoofdstuk,
waarin het gedrag van blokken uitgebreid wordt behandeld en getoond.
Voor het onderbreken van een lijn is de keuze gemaakt voor het breken in twee
afzonderlijke lijnstukken. Er is een alternatief om de blokken te voorzien van een
“wipeout”, waarbij het lijkt alsof je met correctie inkt de lijn wit maakt en daarna het
symbool er overheen tekent. Deze methode bespaart een programmeur veel tijd.
De reden dat deze methode toch niet is gekozen, is de systeem variabele
“sortents”, die volgorde van overlappende objecten bepaalt. De lijnen onder de
16
“wipeouts” kunnen zichtbaar worden wanneer de instelling van “sortents” wordt
verandert.
IV-Industrie verzorgt tekenwerk voor meerdere klanten. De mogelijkheid bestaat
dat een klant een programma of macro gebruikt die “sortents” op een andere
waarde instelt. Wat vervolgens met de tekeningen gebeurt die door IV-Industrie
worden aangeleverd is niet te voorspellen.
6.1.2 Kopiëren van een blok
Voor het kopiëren van een blok moet een commando worden geselecteerd in de
“toolpalette”: Blok kopiëren
Daarna wijst de tekenaar in de tekening een blok aan, vervolgens een punt op de
lijn, waarna het blok wordt gepositioneerd.
6.1.3 Verplaatsen van een blok
Voor het verplaatsen van een blok selecteert de tekenaar in de “toolpalette”:
Blok verplaatsen
Daarna wijst de tekenaar in de tekening het te verplaatsen blok aan.
Vervolgens wijst hij een punt aan op de lijn waar het blok moet komen.
Zodra het blok geselecteerd is, worden de lijnen aan weerszijden van het blok
samengevoegd tot één lijn. De lijn wordt gerepareerd door een VBA programma.
Na het repareren van de lijn wordt het blok gepositioneerd.
6.1.4 Verwijderen van een blok
Het verwijderen van een blok wordt geactiveerd via het commando:
Blok verwijderen
De tekenaar selecteert het blok. Vervolgens verdwijnt dit blok en wordt de
oorspronkelijke lijn weer gerepareerd.
6.1.5 Het gedrag van blokken
Wanneer een blok op een niet-horizontale lijn wordt geplaatst zal deze evenals de
attributen geroteerd worden. Bij sommige blokken is het wenselijk bepaalde
attributen altijd horizontaal te presenteren.
Ook komen er blokken voor die nooit geroteerd mogen worden. Wordt zo’n blok op
een verticale lijn geplaatst dan zal deze niet geroteerd worden.
17
Dus: Het gedrag van de blokken moet worden beïnvloed.
Hiervoor is een VBA programma gemaakt waarmee parameters aan het blok
kunnen worden toegevoegd. Zonder toevoeging van deze parameters zal elk blok
zich op de standaard wijze gedragen.
In de volgende paragrafen is te zien wat de invloed is van de blokparameters.
6.1.5.1 Standaard methode
Het blok zal met alle attributen gedraaid worden wanneer het op een niet-
horizontale lijn wordt geplaatst. Zie de tekening hieronder.
Deze methode is gebruikelijk bij leiding onderdelen en appendages. Appendages
zijn o.a. afsluiters, filters en condenspotten. Leidingonderdelen zijn o.a.
verloopstukken, balgen, passtukken en materiaalovergangen.
18
6.1.5.2 Horizontale attributen bij gedraaid blok
Bij instrument symbolen is het gebruikelijk dat tag nummers en instrument
instellingen horizontaal komen te staan.
Bijvoorbeeld “RD-112”, “SET AT” en “2 barg”. Zie onderstaande tekening.
19
6.1.5.3 Blokken die niet roteren
Sommige instrument blokken worden altijd horizontaal gepresenteerd. Wanneer
ze op een vertikale lijn worden geplaatst zullen ze niet roteren. De lijn wordt wel
onderbroken. Deze situatie komt voor bij nivo-metingen van tanks.
In de tekening hieronder is de niveau meting LICA-356 geplaatst in de verticale
lijn.
20
6.1.5.4 Xdata aan blokken toevoegen
De combinatie van blok-parameters met rotatie-parameters in dynamische blokken
is bepalend voor het gedrag van het blok.
Het gedrag van een blok kan worden ingesteld met een programma dat
kenmerkende gedrags eigenschappen kan toevoegen aan het blok. Deze
eigenschappen worden ondergebracht in extra datavelden die aan het blok
gekoppeld worden.
Deze extra data is binnen AutoCad bekend onder de naam “Xdata”.
Een uitgebreide uitleg van “Xdata” is te lezen in paragraaf 7.2.
Het programma wordt geactiveerd via de “toolpalette” met het commando
Blok parameters
Dit commando opent het volgende formulier.
Wanneer de bovenstaande opties zijn gekozen zullen twee “Xdata” velden worden
toegevoegd aan het blok.
Deze “Xdata” is niet gekoppeld aan de blok definitie maar wordt gekoppeld aan
elke subentiteit van het blok.
Aanvankelijk koppelde het programma de “Xdata” aan de blokdefinitie met VBA
commando: “Call Thisdrawing.Blocks(“regelklep”).SetXdata(datatype, data)
Deze methode functioneert uitstekend binnen de tekening.
Echter na wegschrijven van zo’n blok met “wblock” blijkt de “Xdata” te zijn
verdwenen.
21
“Xdata” die is toegevoegd aan een subentiteit blijft wel behouden na “wblock”.
Voor dit programma is gekozen elke subentiteit te voorzien van “Xdata” om zeker
te zijn van de werking van het programma.
Een alternatief voor “Xdata” was om onzichtbare attributen te gebruiken. Deze
methode is zeker zo betrouwbaar maar minder gebruiksvriendelijk.
6.2 Dynamische blokken
Er zijn verscheidene blokken aangemaakt met dynamische parameters. Achteraf
wijzigen van blokken is immers eenvoudiger dan een nieuw blok aan te maken.
Winstpunt is dat het aantal blokken in de bibliotheek beperkt blijft.
Bij dynamische blokken wordt slechts het uiterlijk veranderd terwijl de inhoud van
de attributen gelijk blijft. Het opnieuw in typen van attribuut waarden resulteert in
directe tijdwinst, en tijdwinst achteraf wegens het voorkomen van typfouten.
Sommige parameters zullen worden gebruikt door de gebruiker andere
voornamelijk door het “blok positioneer programmadeel”.
6.2.1 Blokparameters voor de gebruiker
De volgende blokparameters zij specifiek bedoeld voor de gebruiker
Visibility, Deze wordt veel gebruikt voor afsluiters, pompen en compressoren. Het
grote voordeel van deze parameter is dat de tekenaar snel een nieuw symbool
kan kiezen zonder de attributen opnieuw in te vullen.
Point parameter / Move actie. Deze combinatie wordt veel gebruikt voor attributen
waarvan de tekst, het symbool of een ander object gaat overlappen. Het voordeel
is dat, attributen die bij elkaar horen, gezamenlijk worden verplaatst. Voor een
tekenaar is dit een simpel maar prettig hulpmiddel
Lookup, Deze wordt nu nog slechts gebruikt voor het kader maar zal in de
toekomst worden gebruikt voor de definitie van een tank symbool. Het tank
symbool zal veruit de meeste vormvariaties krijgen. Via een Lookup tabel is hierin
structuur aan te brengen. De definitie van het tanksymbool is één van de vervolg
acties na dit project.
22
6.2.2 Blokparameters voor VBA
Een blok kan maximaal twee rotatieparameters hebben die door het programma
bestuurd worden. Dit wil niet zeggen dat deze parameters niet door de tekenaar
mogen worden gebruikt. Sterker nog, ze zijn bijzonder handig voor tekenaars die
niet in het bezit zijn van de VBA programma’s.
Rotatie parameters:
• Rotatie parameter voor het Instrument tagnummer zie fig.6.2.2A. De naam
van deze rotatie parameter is “hoek tagnummer”.
• Rotatie parameter voor appendage gegevens. In het voorbeeld van
fig.6.2.2B wordt de parameter gebruikt voor het appendage nummer en de
leiding diameter. De parameter naam is “hoek appendage attributen”.
De laatste rotatie parameter is toegevoegd omdat sommige klanten, zoals één
klant waarvoor ik twee jaar heb gewerkt, als de norm hebben dat appendage
attributen horizontaal staan in de PID’s.
Er is een programma gemaakt dat achteraf met één handeling alle attributen
horizontaal zet. Dit programma is dermate klantspecifiek dat het niet meer in dit
verslag verder wordt toegelicht.
Door rotatie parameters herkenbare namen te geven kunnen ze door het
programma worden herkend en gestuurd.
In par. 7.1.1 programma stap 14 wordt uitgelegd hoe het VBA programma de
rotatie parameter “hoek tagnummer” op de juiste stand zet.
Fig.6.2.2A Fig.6.2.2B
23
6.3 Leidingen
Leidingen worden op PID’s weergegeven als ononderbroken lijnen. Daarbij wordt
onderscheid gemaakt tussen hoofdleidingen en subleidingen. Hoofdleidingen
worden dik getekend (0.7 mm) en subleidingen dun (0.35 mm).
De lagen en kleuren zullen in overleg met klanten worden bepaald.
Leidingen behoren te worden voorzien van een leidingnummer. Dit nummer is
meestal opgebouwd uit verschillende onderdelen wat kan bestaan uit drie tot
meerdere onderdelen. De drie meest gebruikte zijn:
• leiding nummer (dit moet uniek zijn)
• de leiding diameter
• de materiaalcode “pipespec.”
Voor het werken met leidingen is een programma gemaakt waarin een aantal
functies zijn verwerkt m.b.t het groeperen van onderdelen die bij een leiding horen.
Tijdens de eerste begrotingsfase kan het handig zijn om per leiding alle
onderdelen op de PID zichtbaar te maken, of om deze weg te schrijven naar een
databestand.
De diverse functies zijn verwerkt in onderstaand formulier.
24
6.3.1 Toekenning van leidingnummers
Toekennen van een leidingnummer vindt plaats via een dialoogbox. Hierin moeten
tekstvelden worden ingevuld die vervolgens worden toegevoegd door objecten te
selecteren. Het veld met het leidingnummer moet verplicht worden ingevuld. De
overige velden kunnen tijdens de engineering fase nog wijzigen.
Het leidingnummer wordt opgeslagen in “Xdata”.
Wanneer een blok wordt geplaatst op een leiding die voorzien is van een
leidingnummer, zal het leidingnummer aan het blok worden gekoppeld. M.a.w. het
blok wordt voorzien van “Xdata”.
Let op! Deze data wordt toegevoegd aan een blok-referentie, terwijl de “Xdata”
die het positioneringgedrag bepaalt wordt toegevoegd aan de subentiteiten van
een blok-definitie.
Dus, alle blokken met dezelfde naam zullen hetzelfde positionering gedrag
hebben, maar niet alle blokken met dezelfde naam krijgen hetzelfde
leidingnummer.
6.3.2 Tonen van een leiding
Een leiding kan, na toekenning van het leidingnummer meteen worden getoond
door de knop aan te klikken onder de tekst “leiding tonen”. Alle onderdelen die zijn
voorzien van een leidingnummer worden uitgelicht. Via VBA is dit zeer eenvoudig
realiseerbaar door van elk object de “property” “highlight” op “true” in te stellen.
Met “regen” wordt de “highlight”ongedaan gemaakt.
6.3.3 Toevoegen en verwijderen van objecten
Normaal wordt een symbool dat in een leiding wordt geplaatst ook meteen
toegevoegd aan de leiding zoals eerder is aangegeven.
Achteraf toevoegen van een object bij een leiding is ook mogelijk.
De functie die objecten verwijderd uit een leidinggroep of objecten van de ene
naar de andere groep overbrengt is nog niet uitgewerkt.
6.3.4 Aanbrengen van leiding labels
Op de PID wordt het leidingnummer altijd aangegeven boven of links van een
leiding. Met de rechter knop kan een label worden geplaatst. De tekenaar hoeft
daarna slechts de leiding aan te wijzen waarna het label verschijnt.
25
6.3.5 Data export
Via de leiding labels kunnen eenvoudig leidinglijsten worden gegenereerd vanuit
de tekening. Ook alle onderdelen per leiding kunnen naar een databestand
worden weggeschreven zoals eerder is vermeld.
Echter deze functie is nog niet in deze programma’s verwerkt maar is wel een
wens voor de toekomst. In verband met de omvang van het project de
ontwikkeling van deze belangrijke functie uitgesteld.
26
7 Uitleg van programma’s Voor het werken met blokken zijn 4 hoofdprogramma’s geschreven.
In paragraaf 6.1 zijn ze reeds vermeld. De twee programma’s die het meest van
elkaar verschillen zullen worden toegelicht.
Daarbij zal aandacht worden besteed aan het toevoegen van “Xdata”
De uitleg wordt ondersteund door stroomdiagrammen “Flowcharts”.
In deze stroomdiagrammen worden verschillende kleuren en lijndikten gebruikt.
De betekenis hiervan is als volgt:
• Groen geeft het begin of het einde aan van een hoofd programma
• Rechthoeken met een dikke lijn geven aan dat de bewerking wordt
uitgevoerd door een subroutine.
• Rechthoeken met een blauwe lijn zijn subroutines waarvan de
stroomdiagrammen in dit verslag zijn opgenomen.
27
7.1 Het plaatsen van een blok
De naam van dit hoofdprogramma is:
Plaats_blok(blok_naam)
In het “toolpalette” zal bij selectie van een blok
het volgende commando kunnen staan:
^C^CPlaats_blok(“afsluiter”)
De naam “afsluiter” wordt als argument aan het
programma meegegeven.
Daarna komen we de eerste subroutine tegen
voor het bepalen van de tekenruimte. Deze
subroutine vertelt het programma of de
tekening in modelspace staat of paperspace.
Immers veel VBA handelingen gaan vooraf
met: Call Thisdrawing.Models
pace of
Call Thisdrawing.Paperspace.
Wanneer de systeem variabele “Tilemode”
gelijk is aan 1, dan krijgt de objectvariabele
“Tekenruimte” obj. “Thisdrawing.Modelspace”
toegewezen en bij 0 “Thisdrawing.Paperspace”.
De volgende invoer handeling vindt plaats in
een subroutine waarin gevraagd wordt om een
punt op een lijn aan te wijzen. Daarbij wordt direct de vangfunctie actief en
ingesteld op “Nearest”. Wijst men naast een lijn wijst, of een ander object dan een
lijn, dan wordt een dialoogvenster getoond waarin gevraagd wordt opnieuw een
punt op een lijn aan te wijzen, of om te stoppen.
Nadat het dialoogvenster wordt afgesloten wordt de variabele “Doorgaan” op
“True” of “False” gezet. Wanneer een lijn is geselecteerd en “Doorgaan” is true zal
het blok worden binnen gehaald. De variabelen “Doorgaan” en “Tekenruimte zijn
globale variabelen en worden ook door andere programma’s gebruikt.
Tenslotte zal het blok worden gepositioneerd volgens één van de drie methoden
uit paragraaf 6.1.5. Hierover volgt uitleg in de volgend paragraaf.
28
7.1.1 Het positioneren van een blok
Voor het positioneren van het blok is een aparte subroutine geschreven.
De VBA naam van deze subroutine is: Positioneer_blok(blk, blok, Ipt)
Tussen haken staan de argumenten die zijn meegegeven door het
hoofdprogramma. De betekenis is
• “blk” is de naam van de blokdefinitie, datatype “string”
• “blok” is het blokobject, datatype “AcadBlockReference”
• “Ipt” is het “Insertion point”, datatype “Variant”
Deze subroutine wordt ook aangeroepen door de programma’s “Kopieer_blok” en
“Verplaats_blok”. Als hulpmiddel voor de beschrijving is het aan te raden de
stroomdiagrammen te raadplegen uit bijlage 1 en 2.
Elke programma stap is genummerd
Stap 1
Hier wordt een selectieset gemaakt op basis van een punt. Het punt dat gebruikt
wordt is het argument “Ipt”. Het lijn object uit deze selectieset wordt toegekend
aan een variable van het type “AcadLine”.
Stap2
2A
In dit programma deel worden gegevens verzameld.
Uit het lijn object wordt de hoek bepaald en toegekend aan “Hoek” (“double”)
De eenheid van de hoek is “radialen”
2B
De leiding gegevens met o.a. het leidingnummer worden uit de “Xdata” van het
lijnobject ingelezen in twee variabelen van het type “Variant”.
De inhoud van deze variabelen moet worden benaderd zoals bij een “array”.
De namen zijn:
• “xt”, Deze variant beschrijft de data typen
• “xd”, Deze variant bevat de gegevens
29
De VBA code is: lijnobject . GetXdata(“HANSTOOLS_PID”, xt, xd). In het eerste argument staat “HANSTOOLS_PID”. Dit is de naam van de
toepassing “application”. Voor selectieset filters die bedoeld zijn voor het
selecteren van objecten met “Xdata”, wordt deze naam als sleutel toegepast.
2C
Als laatste worden de blokparameters van het blok bepaald.
Deze blokparameters zijn ook als “Xdata” opgeslagen, maar zijn opgenomen in de
blokdefinitie. De variabelen zijn van hetzelfde datatype als hiervoor.
De namen zijn: “xt1” en “xd1”.
De “Xdata” wordt ingelezen uit de eerste subentiteit van het blok.
Eerst moet de blokdefinitie worden opgevraagd. De programma code is:
Dim blokdef as AcadBlock Set blokdef = Thisdrawing.Blocks(blk). “blk” is de naam van het blok dat als argument door het hoofdprogramma
meegegeven.
Vervolgens wordt de “Xdata” ingelezen in de variabelen “xt1”, en “xd1”.
De programma code is:
Call blokdef.Item(0).GetXdata(“HANSTOOLS”, xt1, xd1). “Item(0)” is de eerste subentiteit.
De naam van de toepassing is nu: “HANSTOOLS”
De functie van deze “Xdata” gegevens is van technische aard en bij de leidingen is
de “Xdata” informatief. De “Xdata” van blokdefinities kan toegepast worden voor
alle soorten schema’s. Bijvoorbeeld voor electrische schema’s, pneumatiek en
hydraulische schema’s. Mede daarom is ook de toevoeging “_PID” weggelaten.
Stap3
Dit is een controle op de aanwezigheid van “Xdata” aan het lijnobject.
Stap4
Wanneer het lijnobject “Xdata” bevat zal het worden overgedragen aan de
blokreferentie “blok”. Vanaf dat moment is het blok opgenomen in de groep
objecten die allen hetzelfde leidingnummer hebben.
30
Stap5
Dit is een controle of dit type blok voorzien is van blokparameters.
Zo nee, ga verder naar A.
Zo ja, ga naar stap 6
Stap6
De blokparameters worden ingelezen. Vanaf dit punt wordt bepaald hoe het blok
zal worden geplaatst. Daarbij wordt ook naar de stand van de leiding gekeken.
Als blijkt, dat de leiding verticaal is, en dat de blokparameter aangeeft dat het blok
horizontaal moet worden geplaatst, zal het programma verder gaan naar stap 7.
In de andere gevallen naar A.
Ten gunste van de uitleg gaan we nu verder met het programmadeel vanaf punt A.
In dit programmadeel komt nog een andere subroutine voor die verderop in het
verhaal wordt beschreven.
Stap 10.
In deze stap wordt een subroutine aangeroepen.
De VBA naam van deze subroutine is: “zoek_snijpunten_blok(bloknaam, brl, brr)”
In deze subroutine worden de breekafstanden van de lijn bepaald.
Wanneer we een blok bekijken in de “Block-editor” dan kunnen we de X-as
vergelijken met die onder het blok loopt en moet worden onderbroken. Aangezien
de posities van alle subentiteiten ook gerelateerd aan zijn aan de oorsprong,
moeten we dus de snijpunten met de X-as berekenen. De X-waarden van deze
snijpunten worden verzameld in een “array” waarvan de grootste en kleinste de
uiterste breekafstanden vertegenwoordigen.
In de volgende paragraaf wordt dieper op de programmastructuur van deze
subroutine in gegaan.
31
Stap 11
Na het bepalen van de breekafstanden moet het blok in de juiste positie worden
geroteerd. Als de lijn waarop het blok wordt geplaatst verticaal is, wordt het blok
90 graden gedraaid. Ook nu wordt een subroutine aangeroepen. In deze
subroutine wordt een correctie gedaan wanneer bijvoorbeeld de hoek van de lijn
270° is i.p.v. 90°. In beide situaties is de lijn verticaal maar wanneer het blok 270°
gedraaid is, blijkt de leesrichting van de attributen 180° te zijn gedraaid. De hoek
van het blok krijgt in dat geval een correctie van 180° (omgerekend naar radialen).
Zie de programma code in de bijlage.
Stap 12
Zie stap 5
Stap 13
Zie stap 6 maar nu wordt bepaald of de tagnummer attributen wel of niet
horizontaal worden geplaatst.
Zo ja; het programma gaat verder met stap 14.
Zo nee; het programma gaat verder met stap 15.
Stap 14
Dit is een subroutine die de tagnummer attributen terug draait naar de horizontale
stand. Waarom terug draaien?
Het blok is in stap 11 in een bepaalde hoek gedraaid. De attributen met
bijvoorbeeld de leiding diameter behoren mee te zijn gedraaid met het blok.
Dit geldt dus niet voor de tagnummer attributen. Zie paragraaf 6.1.5.2
Stap 15
Het blok is in de goede positie gezet evenals de attributen, maar nu moet de lijn
nog worden onderbroken. Normaal gesproken gebeurt dit ook. Behalve wanneer
het een blok betreft dat de lijn niet snijdt. Een voorbeeld hiervan is het leiding
nummer dat boven de lijn lijkt te zweven.
Wanneer de breekafstanden verschillen in waarde betekent dit dat de lijn moet
worden onderbroken.
32
Stap 16
De breekafstanden zijn in stap 10 al bepaald. De lijn wordt gebroken met:
Call breek_proces_lijn(Ipt, ln, hoek, br_links, br_rechts) De argumenten:
• Ipt, Het “Insertion point” van het blok, datatype “variant” (array).
• Ln, Lijn object, datatype “AcadLine”
• Hoek, De hoek (stap 2A), datatype “double”
• br_links, De linker breek afstand vanaf het “Insertion point”, “double”.
• br_rechts, De rechter breek afstand vanaf het “Insertion point”, “double”.
33
7.1.1.1 Het bepalen van de breek afstanden
In de vorige paragraaf is bij de bespreking van stap 10 al beschreven wat de
subroutine “zoek_snijpunten_blok(bloknaam, brl, brr)” doet.
Deze paragraaf beschrijft hoe de breekafstanden worden bepaald.
Verklaring argumenten:
• bloknaam, de naam van de blokdefinitie, datatype “string”
• brl, de kleinste afstand t.o.v. de oorsprong. Deze afstand is meestal negatief
omdat meestal links en rechts van het “insertionpoint” wordt gebroken. Het
datatype is “double”
• brr, de grootste afstand t.o.v. de oorsprong, datatype “double”
De subroutine krijgt de naam van het blok als argument mee waarna de
blokdefinitie (“AcadBlock” object) wordt toegewezen aan objectvariabele “blkdef”.
Daarna start een programma lus die voor elke subentiteit een aantal bewerkingen
laat uitvoeren. De VBA code van de programma lus is:
For Each elem In blkdef (stap 2)
Stap3..6 uitvoeren!
Next elem (stap 6)
In de stappen 3 t/m 6 worden de x-waarden van de snijpunten bepaald voor:
• lijnen
• cirkels
• arcs
Waarom niet voor polylijnen en ellipsen.
Het opnemen van deze entiteiten in de programmalus heeft geen prioriteit
gekregen want:
• Polylijnen zijn niet strikt nodig voor schema symbolen, dit geldt voor alle
soorten schema’s. De hoeveelheid werk voor het schrijven voor programma
code stond niet in verhouding tot grootte van het probleem.
• Voor ellipsen geldt dezelfde reden als bij polylijnen, en ellipsen zijn door mij
nog niet waargenomen in PID symbolen. Behalve dan bij tanks waar dit
programma niets mee doet.
34
De stappen in het stroomdiagram. Voor het stroomdiagram zie bijlage 3
Voor de programma code zie de bijlage.
Stap 1
Hier wordt het aantal subentiteiten van het blok bepaald.
Stap 2
Hier wordt getest of het laatste element van het blok de stappen 3 t/m 6 heeft
doorlopen
Stap3 Is de subentiteit een lijn?
Zo ja? Ga naar stap 3.1
Stap 3.1
De X-waarde van het snijpunten met de X-as wordt uitgerekend door de
subroutine aanroep: Call snijpunt_lijn(elem, brl, brr)
Waarom heb ik het over snijpunten?
Welnu; wanneer de lijn-subentiteit samenvalt met de X-as beschouwen we dit als
twee snijpunten. De reden dat er toch twee snijpunten worden bepaald is dat de
lijndikte van de subentiteit bij symbolen meestal niet groter is dan 0.35mm terwijl
de lijn waarop het blok geplaatst wordt 0.7mm kan zijn (bij hoofd proceslijnen).
In dat geval moet de lijn dus toch worden gebroken.
Voor de programma code zie de bijlage.
Stap 3.2
De afstanden in de variabelen brl en brr worden toegevoegd aan de dynamische
array “snijpunten_lijst”. Eigenlijk is de naam verkeerd gekozen, daar het gaat om
de X-waarden van de snijpunten.
Telkens als er een subroutine aanroep plaatsvindt voor het berekenen van deze
waarden, wordt de dynamische array met twee geheugenlocaties uitgebreid. De
VBA code is : “ReDim Preserve” snijpunten_lijst(nieuw aantal geheugenplaatsen).
ReDim geeft aan dat we de grootte van de array gaan aanpassen.
35
Preserve geeft aan dat we de oorspronkelijke inhoud van de “array” cellen willen
behouden. Tussen de haken staat het getal dat de nieuwe omvang van het “array”
aangeeft.
Stap4 Is de subentiteit een cirkel?
Zo ja? Ga naar stap 4.1
Stap 4.1
De X-waarden van de snijpunten met de X-as worden uitgerekend door de
subroutine aanroep: Call snijpunt_cirkel(elem, brl, brr)
Als de cirkel de X-as snijdt krijgen brl en brr elk een verschillende waarde.
Als de cirkel de X-as raakt krijgen brl en brr dezelfde waarde.
Als de cirkel boven de X-as ligt blijven brl en brr leeg.
De getallenlijst met afstanden wordt in dat geval 1 of 2 keer aangevuld met de
waarde empty” of de vorige waarde van brl en/of brr.
Stap 4.2
Zie stap 3.2
Stap 5 Is de subentiteit een arc?
Zo ja, ga naar stap 5.1
Zo nee, ga naar de volgende subentiteit.
Stap 5.1
De X-waarden van de snijpunten met de X-as worden uitgerekend door de
subroutine aanroep: Call snijpunt_arc(elem, brl, brr)
In deze subroutine worden de snijpunten bepaald van de denkbeeldige cirkel die
samenvalt met de arc. Vervolgens wordt van de gevonden snijpunten getest of ze
al dan niet op de arc liggen. Ligt een snijpunt daadwerkelijk op de arc dan zal de
x-waarde worden toegevoegd aan de getallenlijst. De snijpunten test wordt
uitgevoerd door een subroutine zie de bijlage.
36
Deze subroutine test of de hoek verdraaiing t.o.v. het centerpunt van de arc, past
tussen de hoekverdraaiingen van het start en eindpunt van de arc.
7.1.1.2 Het bepalen van de verticale breek afstanden
Deze subroutine wordt toegepast in de volgende situatie:
Het blok blijf horizontaal staan wanneer het op een verticale lijn geplaatst wordt.
Zie paragraaf 6.1.5.3.
De werking van deze subroutine is vrijwel identiek aan die van de vorige paragraaf
De VBA naam is: “zoek_snijpunten_blok_vert(bloknaam, brl, brr)”
Aan de naam is de extensie “_vert” toegevoegd om aan te geven dat deze
subroutine van het blok de breekafstanden bepaalt voor een verticale lijn.
De afstanden die in de vorige subroutine werden berekend waren gerelateerd aan
uiterste snijpunten van subobjecten met de X-as.
Wanneer de snijpunten waren berekend werden ook de x-waarden van de
snijpunten in de getallenlijst gezet.
In tegenstelling tot de vorige paragraaf worden de snijpunten met de Y-as
bepaald. De afstanden die in de getallenlijst terecht komen zijn nu de y-waarden
van de snijpunten. Deze verschillen zijn zichtbaar in de subroutines waarin per lijn,
cirkel en arc de afstanden berekend worden.
De aanroep van deze subroutines is nogal voorspelbaar:
• Call snijpunt_lijn_vert(elem, brl, brr)
• Call snijpunt_cirkel_vert(elem, brl, brr)
• Call snijpunt_arc_vert(elem, brl, brr)
De programmacode is te vinden in de bijlage.
37
7.2 Xdata toevoegen
De de voorgaande programma’s maakten gebruikt van “Xdata” die door andere
programma’s waren toegevoegd. Er is “Xdata” aan leidingen, aan subentiteiten
van blokken toegevoegd.
Een AutoCad tekening is eigenlijk een database tabel. Deze tabel bestaat uit
regels en elke regel stelt daarin een AutoCad object voor. Dus objecten als lijnen,
cirkels, polylijnen enz.
Elke regel in de database tabel heeft een vast aantal velden. In die velden staan
de bekende eigenschappen als kleur, lijndikte, beginpunt, eindpunt, laag, enz.
“Xdata” is niets anders dan van velden toevoegen aan een zo’n database regel.
Het gaat hier dus om extra data wat wellicht de naam “Xdata” verklaart.
Elk veld dat een eigenschap beschrijft bestaat op zijn beurt uit twee subvelden.
Het eerste subveld vertelt wat voor eigenschap het is en de tweede vertelt iets
over die eigenschap.
Voorbeeld van een eigenschap is:
• Subveld 1, Kleur,
• Subveld 2, Groen,
Het eerste subveld staat voor het type informatie (“datatype”) en het tweede voor
de inhoud (“data”). In het eerste subveld staat uiteraard niet “Kleur” maar een code
die aangeeft dat het om kleur gaat. Dit is de “DXF code” en voor kleur is dit: 62
Subveld 2 bevat het getal 3 wat overeenkomt met groen.
Alle datatypen zijn in AutoCad te vinden in het overzicht van de “DXF” codes.
Voor dit een overzicht verwijs ik naar de helpfile van AutoCad en voor een heldere
uitleg over dit onderwerp naar het Leerboek en Naslagwerk van ir. R. Boeklagen.
Een “Xdata” veld ook duidelijk te herkennen aan de datatype (“DXF”) code.
“Xdata” krijgt altijd een code die ligt tussen 1000 en 1071.
Code 1001 is verplicht voor subveld 1 en betekent dat subveld 2 moet worden
gevuld met de applicatie naam, een string van maximaal 31 karakters. De andere
codes die binnen dit project worden toegepast zijn 1000 en 1002.
Code 1000 betekent dat subveld 2 een string is van maximaal 255 karakters.
Code 1002 geeft aan dat subveld 2 een begin of einde markeer karakter bevat.
Dit zijn respectievelijk de karakters “{“ en “}”.
38
7.2.1 Leidingnummers toegvoegen
Voor het toevoegen van leidingnummers wordt het volgende formulier geopend.
De programmacode is te vinden in de bijlage.
In dit formulier zijn diverse functies verwerkt die in hoofdstuk 6 zijn besproken.
Nog niet alle functies zijn goed door ontwikkeld in dit programma evenals de
foutafhandeling en de gebruiksvriendelijkheid. Dit staat op de wensenlijst voor de
periode na de afstudeeropdracht.
Het toevoegen van leidingnummers aan objecten is voor dit verhaal heel
interessant om nader toe te lichten. Mede omdat de leiding informatie ook in de
voorgaande programma’s aan bod kwam. Verder is dit een goed voorbeeld om te
tonen hoe “Xdata” aan een object wordt toegevoegd.
Het bovenstaande formulier incl. de ingevulde velden wordt als voorbeeld gebruikt
bij de uitleg op de volgende pagina.
39
7.2.1.1 Uitleg
In het formulier moet ten minste het veld van het leidingnummer zijn ingevuld.
Wanneer de linker knop wordt bediend zal de ingevulde informatie in “Xdata”
velden worden opgeslagen, die aan elk geselecteerd object worden toegevoegd.
Eerst moeten de velden worden opgeslagen in twee “array’s”.
De eerste “array” bevat datatype codes en de tweede “array” bevat de data. De
onderstaande tabel toont de inhoud van de “array’s”.
Cel nr Array “xt”
- Data type - Array “xd”
- Data -
0 1001 “HANSTOOLS_PID”
1 1002 “{“
2 1000 “080”
3 1000 “P02003”
4 1000 “10A1”
5 1000 “W-isol.”
6 1000 “20mm”
7 1000 “heat.tr.”
8 1000 “”
9 1000 “”
10 1002 “}”
De “array’s” zijn in VBA als volgt gedefinieerd:
Dim xt(0 to 10) as integer
Dim xd(0 to 10) as variant
De data wordt tenslotte toegevoegd met de VBA code:
Call object.SetXData(xt, xd) “object” is een AutoCad entiteit als lijn, cirkel, arc, blokreferentie enz.
40
7.2.2 Blokparameters toevoegen
Zoals eerder is vermeld in de vorige paragrafen wordt het gedrag van blokken
bepaald door de blokparameters. Eveneens is verteld dat deze parameters zijn
ondergebracht in “Xdata” velden die toegevoegd zijn aan de subentiteiten van een
blok. Daarmee is de “Xdata” uniek voor het type blok ofwel de blokdefinitie.
Met het onderstaande formulier kunnen de blokparameters worden toegevoegd of
gewijzigd:
Volgens dit voorbeeld zal de informatie als volgt in de “array’s” verwerkt zijn.
Cel nr Array “xt”
- Data type -Array “xd”
- Data -
0 1001 “HANSTOOLS”
1 1002 “{“
2 1000 “NORMAAL”
3 1000 “BLOK HORIZONTAAL”
4 1002 “}”
De array’s worden als volgt gedefinieerd
Dim xt(0 to 4) as integer
Dim xd(0 to 4) as variant
In een programmalus wordt voor elke subentiteit “Xdata” toegevoegd.
Call bl.Item(i).SetXData(xt, xd)
Hierin is “bl” de blokdefinitie en Item(i) subentiteit (i).
Voor de volledige programma code zie de bijlage.
41
8 Conclusie De doelstelling was kwaliteitsverbetering en tijdwinst.
Met de tekenhulpmiddelen die nu al zijn ontwikkeld kan m.i. de conclusie worden
gemaakt dat de doelstelling geslaagd is. Het werken met blokken ervaar ik als
heel gebruiksvriendelijk en de dymanische blokken die zijn aangemaakt zijn heel
flexibel in het gebruik. Waardoor ze voor klanten die niet in het bezit zijn van de
VBA programma’s, makkelijk achteraf zijn aan te passen. Als voorbeeld bedoel ik
het groepsgewijs roteren of verplaatsen van attributen.
Het subdoel was brede toepasbaarheid.
De tekenhulpmiddelen voor het manipuleren van blokken kunnen ook worden
gebruikt voor elektrotechnische symbolen, en symbolen voor ander type
schema’s. Hieruit kan ik concluderen dat het subdoel is bereikt.
Voor de dynamische blokken ligt dit anders. Fysiek zijn ze niet voor andere
toepassingen geschikt. Maar de basisconcepten zijn wel bruikbaar voor andere
toepassingen.
Tijdens de ontwikkeling van dit project neemt de kennis en ervaring snel toe.
Daardoor wordt in steeds minder tijd programma code aangemaakt. Een ander
gevolg hiervan is dat ik steeds kritischer ben geworden over gekozen oplossingen.
Daardoor is de methode komen te vervallen waarbij breekafstanden van blokken
in onzichtbare attributen waren opgeslagen.
De nieuwe methode is kwalitatief veel beter, breder toepasbaar en bespaart tijd.
Hiermee wordt bedoeld, het uitrekenen van de breekafstanden door VBA. Hetgeen
de gebruiker bij de samenstellen van bibliotheken de tijd bespaart die nodig is om
van elk blok de breekafstanden handmatig te bepalen en in te vullen.
Ondertussen heb ik door de opgedane ervaring, aangevuld met een dosis
enthousiasme, twee kleine automatiserings projecten mogen doen.
Voor beide projecten zijn tekeningen automatisch gegenereerd vanuit een Excel
bestand. In totaal waren dit 100 tekeningen waarvan de hoeveelheid tekenwerk
was geschat op 3 weken. Het werk is, inclusief programmeren, is in 1 week
voltooid. Door het succes van dit werk ben ik benaderd om mee te discussiëren
over een project van enkele manjaren aan tekenwerk waarvan verteld wordt dat
veel informatie in Access database bestanden is opgeslagen.
42
9 Nawoord Zoals al eerder vermeld heb ik inmiddels veel ervaring en inzicht gekregen
waardoor de drempel om complexere problemen aan te pakken volledig is
verdwenen en heeft plaats gemaakt voor nieuwe uitdagingen.
Erkenning krijg ik inmiddels meer dan ik had verwacht. Wellicht is dit ook te
danken aan de liefde voor de materie waardoor je veel enthousiasme kunt
overbrengen naar anderen. Een voorbeeld is het enthousiasme waarmee een
collega pas via mij (lees TEC Cad College) het gemak van toolpalettes heeft
ontdekt en sindsdien c.a. 500 symbolen hierin heeft verwerkt.
Als kroon op al het gedane werk hoop ik binnenkort de certificering van ACE
System Manager te behalen.
Wat m.i. veel aandacht verdient is de deskundigheid van TEC cad-college.
Zoveel expertise op zo’n klein oppervlak ben ik op CAD gebied nog niet eerder
tegengekomen.
43
44
Bijlage 1
45
Bijlage 2
46
Bijlage 3
47 47
Bijlage 4 Sub plaats_blok(blok_naam) Dim Ipoint As Variant Dim Blokref As AcadBlockReference Call Tekenruimte_bepalen Doorgaan = True Ipoint = punt_op_lijn_aanwijzen If Doorgaan = False Then Exit Sub Else Set Blokref = Tekenruimte.InsertBlock(Ipoint, blok_naam, 1, 1, 1, 0) Call Positioneer_Blok(blok_naam, Blokref, Ipoint) End If End Sub
Sub verwijder_blok() Dim blk As AcadBlockReference 'selecteer te kopieren blok Set blk = selecteer.enkel_blok If Doorgaan = False Then Exit Sub Else Call repareer_proces_lijn(blk) blk.Delete End If End Sub
Sub verplaats_blok() Dim blk As AcadObject Set blk = selecteer.enkel_blok If Doorgaan = False Then Exit Sub Else Call repareer_proces_lijn(blk) Naam = blk.EffectiveName Ipoint = blk.InsertionPoint p1 = punt_op_lijn_aanwijzen Call blk.Move(Ipoint, p1) 'draai het blok weer naar 0 graden. Call blk.Rotate(p1, (0 - blk.Rotation)) Call Positioneer_Blok(Naam, blk, p1) End If End Sub
48
Bijlage 5
Sub kopieer_blok() Dim ss As AcadSelectionSet Dim blk As AcadBlockReference Dim Blk_Nieuw As AcadBlockReference Dim br_links, br_rechts As Double Dim pt, Ipoint, p2 As Variant Dim Naam As String Dim attrs_oud, attrs_nieuw As Variant Dim Dyn_props As Variant Dim Visibility_name As String Dim aant, Dyn_index As Integer Dim Visibility_aanwezig As Boolean 'selecteer te kopieren blok Set blk = selecteer.enkel_blok If Doorgaan = False Then Exit Sub Else 'Belangrijke gegevens uit het te kopieren blok halen 'die later worden overgezet naar het nieuwe blok attrs_oud = blk.GetAttributes Dyn_props = blk.GetDynamicBlockProperties If IsArray(Dyn_props) Then aant = UBound(Dyn_props) For i = 0 To aant If Dyn_props(i).PropertyName = "Visibility" Then Visibility_name = Dyn_props(i).Value Dyn_index = i Visibility_aanwezig = True End If Next i End If Naam = blk.EffectiveName Ipoint = blk.InsertionPoint Set Blk_Nieuw = blk.Copy 'attribuut waarden van blok overnemen attrs_nieuw = Blk_Nieuw.GetAttributes For i = 0 To UBound(attrs_nieuw) attrs_nieuw(i).TextString = attrs_oud(i).TextString Next i 'Visibility van blok overnemen If Visibility_aanwezig Then Blk_Nieuw.GetDynamicBlockProperties(Dyn_index).Value = Visibility_name End If p1 = punt_op_lijn_aanwijzen If Doorgaan = False Then Exit Sub Else Call Blk_Nieuw.Move(Ipoint, p1) 'draai het blok weer naar 0 graden. Call Blk_Nieuw.Rotate(p1, (0 - Blk_Nieuw.Rotation)) Call Positioneer_Blok(Naam, Blk_Nieuw, p1) End If End If End Sub
49
Bijlage 6
Sub repareer_proces_lijn(blk) Dim sslinks, ssrechts As AcadSelectionSet Dim PL, PR, sp, ep, p1, p2, P3, P4 As Variant Dim links, rechts, hoek, hoek_rnd As Double Dim aant1, aant2, i As Long Dim llijn, rlijn, nieuwe_lijn, volgende_lijn As AcadLine Dim Naam, blk_naam, blk_param As String Dim ft(0) As Integer Dim fd(0) As Variant Dim Afstanden(0 To 3) As Double 'selectieset filter ft(0) = 0 fd(0) = "LINE" Call Tekenruimte_bepalen 'declaraties voor xdata Dim xd, xt As Variant 'xdata van lijn Dim xd1, xt1 As Variant 'xdata van bloktype 'gegevens ophalen van het bloktype blk_naam = blk.EffectiveName hoek = blk.Rotation 'blk_param = ThisDrawing.Blocks(blk_naam).Item(0).GetXData("HANSTOOLS", xt1, xd1) If Round(hoek, 1) = 0# Then Call zoek_snijpunten_blok_vert(blk_naam, links, rechts) PL = ThisDrawing.Utility.PolarPoint(blk.InsertionPoint, (pi / 2), links) Set sslinks = selecteer.sst_filter(ft, fd, "crossing", PL, PL) aant1 = sslinks.Count sslinks.Delete PR = ThisDrawing.Utility.PolarPoint(blk.InsertionPoint, (pi / 2), rechts) Set ssrechts = selecteer.sst_filter(ft, fd, "crossing", PR, PR) aant2 = ssrechts.Count ssrechts.Delete If aant1 = 0 And aant2 = 0 Then Call zoek_snijpunten_blok(blk_naam, links, rechts) PL = ThisDrawing.Utility.PolarPoint(blk.InsertionPoint, hoek, links) PR = ThisDrawing.Utility.PolarPoint(blk.InsertionPoint, hoek, rechts) Else If aant1 > 1 Or aant2 > 1 Then MsgBox ("Het blok grenst aan, of ligt op overlappende lijnen") Exit Sub Else If aant1 = 1 And aant2 = 1 Then GoTo Repareren Else Exit Sub End If End If End If Else Call zoek_snijpunten_blok(blk_naam, links, rechts) PL = ThisDrawing.Utility.PolarPoint(blk.InsertionPoint, hoek, links) PR = ThisDrawing.Utility.PolarPoint(blk.InsertionPoint, hoek, rechts) End If
Ga verder naar bijlage 7
Bijlage 7
50
Repareren: 'selecteer de lijn aan de linker/onderkant van het blok Set sslinks = selecteer.sst_filter(ft, fd, "crossing", PL, PL) aant1 = sslinks.Count If aant1 = 1 Then Set llijn = sslinks.Item(0) Call llijn.GetXData("HANSTOOLS_PID", xt, xd) Else If aant1 > 1 Then MsgBox ("Het blok grenst aan, of ligt op overlappende lijnen") End If Exit Sub End If sslinks.Delete 'selecteer de lijn aan de rechter/bovenkant van het blok Set ssrechts = selecteer.sst_filter(ft, fd, "crossing", PR, PR) aant2 = ssrechts.Count If aant2 = 1 Then Set rlijn = ssrechts.Item(0) Else If aant2 > 1 Then MsgBox ("Het blok grenst aan, of ligt op overlappende lijnen") End If Exit Sub End If ssrechts.Delete If rlijn.Handle <> llijn.Handle Then p1 = llijn.StartPoint: p2 = llijn.EndPoint P3 = rlijn.StartPoint: P4 = rlijn.EndPoint sp = p1: ep = P3 a1 = afstand(p1, P3): a2 = afstand(p1, P4): a3 = afstand(p2, P3): a4 = afstand(p2, P4) If a1 < a2 Then ep = P4 If a2 < a4 Then sp = p2 End If Else If a1 < a3 Then sp = p2 End If End If llijn.StartPoint = sp: llijn.EndPoint = ep rlijn.Delete End If End Sub
51
Bijlage 8
Sub Positioneer_Blok(blk, blok, Ipt) Dim blokdef As AcadBlock Dim ss_ln As AcadSelectionSet Dim ln As AcadLine Dim br_links, br_rechts As Double Dim hoek, hoek_deg, hoek_rnd As Double Dim xt, xd, xt1, xd1 As Variant 'gegevens ophalen van de lijn waarop het blok geplaatst wordt. Set ss_ln = selecteer.ss_point(Ipt) If Doorgaan = False Then Exit Sub End If Set ln = ss_ln.Item(0) ss_ln.Delete hoek = ln.Angle: hoek_deg = rad_to_deg(hoek): hoek_rnd = Round(hoek_deg, 0) Call ln.GetXData("HANSTOOLS_PID", xt, xd) 'toe te voegen data aan te plaatsen blok 'Blok krijgt leidinggegevens If IsArray(xd) Then Call blok.SetXData(xt, xd) End If 'gegevens ophalen van het bloktype Set blokdef = ThisDrawing.Blocks(blk) Call blokdef.Item(0).GetXData("HANSTOOLS", xt1, xd1) If IsArray(xd1) Then If xd1(3) = "BLOK HORIZONTAAL" And (hoek_rnd = 90 Or hoek_rnd = 270) Then Call zoek_snijpunten_blok_vert(blk, br_links, br_rechts) If br_links <> br_rechts Then Call breek_proces_lijn(Ipt, ln, hoek, br_links, br_rechts) End If Exit Sub End If End If Call zoek_snijpunten_blok(blk, br_links, br_rechts) Call roteer_blok(blok, Ipt, hoek, hoek_deg) If IsArray(xd1) Then If xd1(2) = "TAGNUMMERS HORIZONTAAL" Then Call zet_attr_horizontaal(blok, "hoek tagnummer") End If End If If br_links <> br_rechts Then Call breek_proces_lijn(Ipt, ln, hoek, br_links, br_rechts) End If End Sub
52
Bijlage 9
Sub breek_proces_lijn(inspoint, lijn, hk, breek_links, breek_rechts) Dim hk_deg As Double Dim nieuwe_lijn, next_lijn As AcadLine Dim xd_type, xd_data As Variant Dim sp, ep, ep_new, brp1, brp2 As Variant Call Tekenruimte_bepalen sp = lijn.StartPoint: ep = lijn.EndPoint: ep_new = ep hk_deg = bereken.rad_to_deg(hk) If ((hk_deg > 90) And (hk_deg <= 270)) Then brp2 = ThisDrawing.Utility.PolarPoint(inspoint, hk, -breek_rechts) brp1 = ThisDrawing.Utility.PolarPoint(inspoint, hk, -breek_links) Else brp1 = ThisDrawing.Utility.PolarPoint(inspoint, hk, breek_rechts) brp2 = ThisDrawing.Utility.PolarPoint(inspoint, hk, breek_links) End If Call lijn.GetXData("HANSTOOLS_PID", xd_type, xd_data) 'oude lijn inkorten lijn.EndPoint = brp2 'nieuwe lijn plaatsen Set nieuwe_lijn = Tekenruimte.AddLine(brp1, ep_new) If IsArray(xd_type) Then If UBound(xd_type) > 5 Then Call nieuwe_lijn.SetXData(xd_type, xd_data) nieuwe_lijn.Layer = lijn.Layer nieuwe_lijn.Linetype = lijn.Linetype nieuwe_lijn.TrueColor = lijn.TrueColor nieuwe_lijn.LinetypeScale = lijn.LinetypeScale nieuwe_lijn.Lineweight = lijn.Lineweight End If End If End Sub
Sub roteer_blok(bk, inspoint, hoek, graden) Dim hoekcheck As Boolean hoekcheck = False Select Case hoekcheck Case hoekcheck = (graden > 90 And graden <= 270) rhoek = bereken.deg_to_rad(graden + 180) Case hoekcheck = (graden > 270 And graden < 360) rhoek = bereken.deg_to_rad(graden - 360) Case hoekcheck = (graden >= 0 And graden <= 90) rhoek = hoek End Select Call bk.Rotate(inspoint, rhoek) End Sub
53
Bijlage 10
Sub zoek_snijpunten_blok(bloknaam, brl, brr) 'zoekt de punten die de x-as snijden. Dit is dus de lijn die door het basepoint/insertionpoint loopt. 'De blok definitie moet daarvoor worden onderzocht en niet het block reference, omdat de subentiteiten 'hierin niet benaderbaar zijn. Dim blkdef As AcadBlock Dim Naam As String Dim aant As Integer Dim snijpunten_lijst() As Variant Set blkdef = ThisDrawing.Blocks.Item(bloknaam) aant = -1 For Each elem In blkdef Naam = elem.ObjectName If Naam = "AcDbLine" Then Call snijpunt_lijn(elem, brl, brr) ReDim Preserve snijpunten_lijst(aant + 2) snijpunten_lijst((aant + 1)) = brl: snijpunten_lijst((aant + 2)) = brr aant = UBound(snijpunten_lijst) End If If Naam = "AcDbCircle" Then Call snijpunt_cirkel(elem, brl, brr) ReDim Preserve snijpunten_lijst(aant + 2) snijpunten_lijst((aant + 1)) = brl: snijpunten_lijst((aant + 2)) = brr aant = UBound(snijpunten_lijst) End If If Naam = "AcDbArc" Then Call snijpunt_arc(elem, brl, brr) ReDim Preserve snijpunten_lijst(aant + 2) snijpunten_lijst((aant + 1)) = brl: snijpunten_lijst((aant + 2)) = brr aant = UBound(snijpunten_lijst) End If Next elem If aant = -1 Then brl = 0#: brr = 0# Exit Sub Else brl = Round(bereken.Kleinste_In_Array(snijpunten_lijst), 4) brr = Round(bereken.Grootste_In_Array(snijpunten_lijst), 4) End If End Sub
54
Bijlage 11
Sub zoek_snijpunten_blok_vert(bloknaam, brl, brr) 'zoekt de punten die de y-as snijden. Dit is dus de lijn die door het basepoint/insertionpoint loopt. 'De blok definitie moet daarvoor worden onderzocht en niet het block reference, omdat de subentiteiten 'hierin niet benaderbaar zijn. Dim blkdef As AcadBlock Dim Naam As String Dim aant As Integer Dim snijpunten_lijst() As Variant Set blkdef = ThisDrawing.Blocks.Item(bloknaam) aant = -1 For Each elem In blkdef Naam = elem.ObjectName If Naam = "AcDbLine" Then Call snijpunt_lijn_vert(elem, brl, brr) ReDim Preserve snijpunten_lijst(aant + 2) snijpunten_lijst((aant + 1)) = brl: snijpunten_lijst((aant + 2)) = brr aant = UBound(snijpunten_lijst) End If If Naam = "AcDbCircle" Then Call snijpunt_cirkel_vert(elem, brl, brr) ReDim Preserve snijpunten_lijst(aant + 2) snijpunten_lijst((aant + 1)) = brl: snijpunten_lijst((aant + 2)) = brr aant = UBound(snijpunten_lijst) End If If Naam = "AcDbArc" Then Call snijpunt_arc_vert(elem, brl, brr) ReDim Preserve snijpunten_lijst(aant + 2) snijpunten_lijst((aant + 1)) = brl: snijpunten_lijst((aant + 2)) = brr aant = UBound(snijpunten_lijst) End If Next elem If aant = -1 Then brl = 0#: brr = 0# Exit Sub Else brl = Round(bereken.Kleinste_In_Array(snijpunten_lijst), 4) brr = Round(bereken.Grootste_In_Array(snijpunten_lijst), 4) End If End Sub
55
Bijlage 12
Public Sub snijpunt_cirkel(circ, br1, br2) Dim cen As Variant Dim R, y, dy, x, dx, sn1, sn2, p, q As Double cen = circ.Center R = circ.Radius y = cen(1) dy = Abs(y) If dy < R Then x = Sqr(R ^ 2 - dy ^ 2) br1 = 0 + cen(0) - x br2 = 0 + cen(0) + x End If End Sub
Public Sub snijpunt_lijn(lijn, br1, br2) Dim ep, sp As Variant Dim sn, sn1, sn2, xx, x, yy, y, f, tmp As Double Dim geen_snijpunt As Boolean Dim horizontaal As Boolean ep = lijn.EndPoint sp = lijn.StartPoint horizontaal = ep(1) = 0 And sp(1) = 0 If horizontaal Then br1 = sp(0) br2 = ep(0) Else geen_snijpunt = (ep(1) > 0 And sp(1) > 0) Or (ep(1) < 0 And sp(1) < 0) If geen_snijpunt Then Exit Sub Else xx = ep(0) - sp(0) yy = ep(1) - sp(1) y = ep(1) f = y / yy x = f * xx br1 = ep(0) - x End If End If End Sub
56
Bijlage 13
Public Sub snijpunt_arc(boog, br1, br2) Dim cen As Variant Dim R, y, dy, x, dx, sn1, sn2, p, q As Double Dim Sp1(0 To 2) As Double Dim Sp2(0 To 2) As Double cen = boog.Center R = boog.Radius y = cen(1) dy = Abs(y) If dy <= R Then x = Sqr(R ^ 2 - dy ^ 2) p = 0 + cen(0) - x q = 0 + cen(0) + x sn1 = Round(p, 6) sn2 = Round(q, 6) 'sp1 en sp2 zijn snijpunten Sp1(0) = sn1: Sp1(1) = 0: Sp1(2) = 0 Sp2(0) = sn2: Sp2(1) = 0: Sp2(2) = 0 If punt_op_arc(boog, Sp1) Then br1 = sn1 End If If punt_op_arc(boog, Sp2) Then br2 = sn2 End If End If End Sub Function punt_op_arc(a, pt1) As Boolean 'Hier wordt bepaald of een punt (pt1) op cirkelboog (a) ligt 'het resultaat is true/false Dim sp, ep, cen As Variant cen = a.Center sa = Round(a.StartAngle, 6) ea = Round(a.EndAngle, 6) a1 = Round(ThisDrawing.Utility.AngleFromXAxis(cen, pt1), 6) If sa > ea Then If a1 >= sa Or a1 <= ea Then punt_op_arc = True Else punt_op_arc = False End If End If If sa < ea Then If a1 >= sa And a1 <= ea Then punt_op_arc = True Else punt_op_arc = False End If End If End Function
57
Bijlage 14
Public Sub snijpunt_lijn_vert(lijn2, br1, br2) Dim ep, sp As Variant Dim sn, sn1, sn2, xx, x, yy, y, f, tmp As Double Dim geen_snijpunt As Boolean Dim horizontaal As Boolean ep = lijn2.EndPoint sp = lijn2.StartPoint horizontaal = ep(0) = 0 And sp(0) = 0 If horizontaal Then br1 = sp(1) br2 = ep(1) Else geen_snijpunt = (ep(0) > 0 And sp(0) > 0) Or (ep(0) < 0 And sp(0) < 0) If geen_snijpunt Then Exit Sub Else 'snijpunt uitrekenen yy = ep(1) - sp(1) xx = ep(0) - sp(0) x = ep(0) f = x / xx y = f * yy br1 = ep(1) - y End If End If End Sub
Public Sub snijpunt_cirkel_vert(circ, br1, br2) Dim cen As Variant Dim R, y, dy, x, dx, sn1, sn2, p, q As Double cen = circ.Center R = circ.Radius x = cen(0) dx = Abs(x) If dx < R Then y = Sqr(R ^ 2 - dx ^ 2) br1 = 0 + cen(1) - y br2 = 0 + cen(1) + y End If End Sub
58
Bijlage 15 Public Sub snijpunt_arc_vert(boog, br1, br2) Dim cen As Variant Dim R, y, dy, x, dx, sn1, sn2, p, q As Double Dim Sp1(0 To 2) As Double Dim Sp2(0 To 2) As Double cen = boog.Center R = boog.Radius x = cen(0) dx = Abs(x) If dx <= R Then y = Sqr(R ^ 2 - dx ^ 2) p = 0 + cen(1) - y q = 0 + cen(1) + y sn1 = Round(p, 6) sn2 = Round(q, 6) 'sp1 en sp2 zijn snijpunten Sp1(0) = 0: Sp1(1) = sn1: Sp1(2) = 0 Sp2(0) = 0: Sp2(1) = sn2: Sp2(2) = 0 If punt_op_arc(boog, Sp1) Then br1 = sn1 End If If punt_op_arc(boog, Sp2) Then br2 = sn2 End If End If End Sub
Sub zet_attr_horizontaal(bl, descr) 'Wordt gebruikt bij dynamische blokken. De rotatie-parameter met omschrijving in parameter "descr" 'krijgt een "value" van 0.0 (double). Dim hoek, hoek_correctie As Double Dim Blk_Defs As Variant Dim Blk_Def As AcadDynamicBlockReferenceProperty Dim i As Integer hoek = bl.Rotation hoek_correctie = 0 - hoek If bl.IsDynamicBlock Then Blk_Defs = bl.GetDynamicBlockProperties For i = 0 To UBound(Blk_Defs) Set Blk_Def = Blk_Defs(i) If Blk_Def.Description = descr Then Blk_Def.Value = hoek_correctie bl.Update 'exit For End If Next i End If End Sub Sub appendage_nummers_horizontaal() Dim ssblk As AcadSelectionSet Dim blk_elem As AcadBlockReference Set ssblk = selecteer.ss_blokken For Each blk_elem In ssblk Call zet_attr_horizontaal(blk_elem, "hoek appendage attributen") Next blk_elem ssblk.Delete End Sub
59
Bijlage 16
Private Sub Cmd_Leidingnr_toevoegen_Click() Dim ss_lnr As AcadSelectionSet Dim xt(0 To 10) As Integer Dim xd(0 To 10) As Variant Dim elem As AcadObject If Me.TextBox_leidingnummer.Value <> "" Then Me.Hide Set ss_lnr = selecteer.sst xt(0) = 1001: xd(0) = "HANSTOOLS_PID" xt(1) = 1002: xd(1) = "{" xt(2) = 1000: xd(2) = Me.TextBox_maat.Value xt(3) = 1000: xd(3) = Me.TextBox_leidingnummer.Value xt(4) = 1000: xd(4) = Me.TextBox_pipespec.Value xt(5) = 1000: xd(5) = Me.TextBox1.Value xt(6) = 1000: xd(6) = Me.TextBox2.Value xt(7) = 1000: xd(7) = Me.TextBox3.Value xt(8) = 1000: xd(8) = "" xt(9) = 1000: xd(9) = "" xt(10) = 1002: xd(10) = "}" For Each elem In ss_lnr 'xd(8) = ? 'xd(9) = ? Call elem.SetXData(xt, xd) Next elem ss_lnr.Delete Else Call MsgBox("Er moet altijd een leidingnummer worden ingevuld", , "Leidingnummer niet ingevuld") End If End Sub
Private Sub Cmd_plaats_leidingnummer_Click() Me.Hide Call PID.plaats_leidingnummer End Sub
Private Sub cmd_toon_leiding_Click() Me.Hide Call PID.toon_gehele_leiding End Sub
Private Sub CommandButton1_Click() Me.Hide End Sub
60
Bijlage 17 Private Sub Cmd_Leiding_uitbreiden_Click() Dim ss_lnr As AcadSelectionSet Dim ln As AcadLine Dim xt As Variant Dim xd As Variant Dim elem As AcadObject Me.Hide start: Set ln = selecteer.enkel_lijnstuk If Doorgaan = False Then GoTo einde Else Call ln.GetXData("HANSTOOLS_PID", xt, xd) If IsArray(xt) Then If IsEmpty(xd(3)) Then MsgBox ("Lijnstuk heeft geen leidingnummer") GoTo start Else Set ss_lnr = selecteer.sst For Each elem In ss_lnr Call elem.SetXData(xt, xd) Next elem ss_lnr.Delete End If Else MsgBox ("Lijnstuk heeft geen leidingnummer") GoTo start End If End If einde: Me.Show End Sub
61
Bijlage 18
Formulier “Xdata” naar blokken Private Sub ok_Click() 'Call blokken.Xdata_naar_blok Dim blok As AcadBlockReference Dim bl As AcadBlock Dim xt(0 To 4) As Integer Dim xd(0 To 4) As Variant Dim aant, i As Integer Call Me.Hide Doorgaan = True Set blok = selecteer.enkel_blok If Doorgaan = False Then Exit Sub End If Set bl = ThisDrawing.Blocks.Item(blok.EffectiveName) 'eerst xdata ophalen indien aanwezig 'daarna aanpassen afhankelijk van optionbuttons Call bl.GetXData("HANSTOOLS", xt, xd) 'If Xd(0) = "HANSTOOLS" Then xt(0) = 1001: xd(0) = "HANSTOOLS" xt(1) = 1002: xd(1) = "{" xt(2) = 1000 xt(3) = 1000 xt(4) = 1002: xd(4) = "}" If Me.CheckBox1.Value = True Then xd(2) = "TAGNUMMERS HORIZONTAAL" Else xd(2) = "NORMAAL" End If If Me.CheckBox2.Value = True Then xd(3) = "BLOK HORIZONTAAL" Else xd(3) = "NORMAAL" End If Call bl.SetXData(xt, xd) 'xdata toekennen aan subentiteiten aant = bl.Count For i = 0 To (aant - 1) Call bl.Item(i).SetXData(xt, xd) Next i Call Xdata.view_xdata_of_block(bl) 'End If End Sub
Private Sub cancel_Click() Me.Hide End Sub
62
Bijlage 19
Function punt_op_lijn_aanwijzen() Dim ss_tmp As AcadSelectionSet Dim Snapmode_org As Long Dim Nearest As Integer Nearest = 512 Snapmode_org = ThisDrawing.GetVariable("osmode") Call ThisDrawing.SetVariable("osmode", Nearest) On Error Resume Next punt_op_lijn_aanwijzen = ThisDrawing.Utility.GetPoint(, "Wijs punt op lijn aan: ") If Err Then Err.Clear Call ThisDrawing.SetVariable("osmode", Snapmode_org) Exit Function End If Set ss_tmp = selecteer.ss_point_lijn(punt_op_lijn_aanwijzen) While ss_tmp.Count = 0 Doorgaan = True Call frm_geen_lijn.Show If Doorgaan = False Then Call ThisDrawing.SetVariable("osmode", Snapmode_org) Exit Function End If punt_op_lijn_aanwijzen = ThisDrawing.Utility.GetPoint(, "Wijs punt op lijn aan: ") Set ss_tmp = selecteer.ss_point_lijn(punt_op_lijn_aanwijzen) Wend Call ThisDrawing.SetVariable("osmode", Snapmode_org) ss_tmp.Delete End Function
Sub appendage_nummers_horizontaal()
Dim ssblk As AcadSelectionSet Dim blk_elem As AcadBlockReference Set ssblk = selecteer.ss_blokken For Each blk_elem In ssblk Call zet_attr_horizontaal(blk_elem, "hoek appendage attributen") Next blk_elem ssblk.Delete
End Sub
63
Bijlage 20
Sub toon_gehele_leiding() Dim obj_A As AcadObject Dim elem As AcadObject Dim pt As Variant Dim xt, xd As Variant Dim leidingnr As String Call Tekenruimte_bepalen Call ThisDrawing.Utility.GetEntity(obj_A, pt) Call obj_A.GetXData("HANSTOOLS_PID", xt, xd) If IsArray(xt) Then If UBound(xt) >= 8 Then leidingnr = xd(3) End If End If For Each elem In Tekenruimte Call elem.GetXData("HANSTOOLS_PID", xt, xd) If IsArray(xt) Then If UBound(xt) >= 8 Then If xd(3) = leidingnr Then elem.Highlight (True) End If End If End If Next elem End Sub
Sub lees_onzichtbare_attributen(bk, brl, brr) 'te gebruiken ingeval de automatische detectie van de breekpunten niet goed werkt bij plaatsing 'van een symbool. Deze situatie doet zich voor als enkele subentiteiten van een symbool 'ellipsen of polylijnen zijn en tevens de begrenzing van het symbool zijn. Dim aant, i As Integer Dim att As AcadObject Dim Naam As String brl = 0: brr = 0 var_atts = bk.GetConstantAttributes aant = UBound(var_atts) 'de onzichtbare attributen welke bepalend zijn voor de grootte van de lijnonderbreking. 'worden uitgelezen (indien ze bestaan) If aant >= 1 Then For i = 0 To aant Set att = var_atts(i) Naam = att.TagString If Naam = "BREEKLINKS" Then brl = CDbl(att.TextString) ElseIf Naam = "BREEKRECHTS" Then brr = CDbl(att.TextString) End If Next i End If End Sub
64
Bijlage 21
Sub plaats_leidingnummer() Dim Ipt As Variant Dim Obj_Lijn As AcadObject Dim rads, degs As Double Dim line_id As String Dim atts As Variant Call Tekenruimte_bepalen Doorgaan = True Ipt = punt_op_lijn_aanwijzen If Doorgaan = False Then Exit Sub Else Set Obj_Lijn = selecteer.single_object_at_point(Ipt) rads = Obj_Lijn.Angle degs = rad_to_deg(rads) Call Obj_Lijn.GetXData("HANSTOOLS_PID", xt, xd) If IsArray(xd) Then If Not (IsEmpty(xd(3))) Then line_id = xd(2) For i = 3 To 7 If xd(i) = "" Then Exit For Else line_id = line_id & "-" & xd(i) End If Next i End If End If Set Blokref = Tekenruimte.InsertBlock(Ipt, "linenr", 1, 1, 1, 0) If line_id <> "" Then atts = Blokref.GetAttributes atts(0).TextString = line_id Blokref.Update End If Call PID.roteer_blok(Blokref, Ipt, rads, degs) End If End Sub
65
Bijlage 22 'converteren van inches naar millimeters Public Function inchtomm(ByVal a As Double) As Double inchtomm = a * 25.4 End Function 'converteren van millimeters naar inches Public Function mmtoinch(ByVal a As Double) As Double mmtoinch = a / 25.4 End Function 'berekenen van pi Public Function pi() As Double pi = 4 * Atn(1) End Function 'berekenen afstand tussen twee 2-dimensionale punten Public Function afstand(a, b) Dim dx, dy As Double dx = b(0) - a(0): dy = b(1) - a(1) afstand = Sqr(dx ^ 2 + dy ^ 2) End Function 'converteren van graden naar radialen Public Function deg_to_rad(ByVal a As Double) As Double deg_to_rad = (a / 180) * pi() End Function 'converteren van radialen naar graden Public Function rad_to_deg(ByVal a As Double) As Double rad_to_deg = (a / pi()) * 180 End Function 'grootste waarde bepalen uit twee getallen Public Function grootste(ByVal a As Double, ByVal b As Double) As Double If a >= b Then grootste = a Else grootste = b End If End Function 'kleinste waarde bepalen uit twee getallen Public Function kleinste(ByVal a As Variant, ByVal b As Variant) As Double If a <= b Then kleinste = a Else kleinste = b End If End Function Public Function Grootste_In_Array(rij) As Double Dim i As Long Dim b As Double aant = UBound(rij) Grootste_In_Array = rij(0) For i = 1 To aant If Not (IsMissing(rij(i))) Then If rij(i) > Grootste_In_Array Then Grootste_In_Array = rij(i) End If End If Next i End Function
66
Bijlage 23
Public Function ABS_Grootste_In_Array(rij) As Double Dim i As Long Dim b As Double aant = UBound(rij) Grootste_In_Array = rij(0) For i = 1 To aant If Not (IsEmpty(rij(i))) Then If Abs(rij(i)) > Grootste_In_Array Then Grootste_In_Array = rij(i) End If End If Next i End Function Public Function Kleinste_In_Array(rij) As Double Dim i As Long Dim b As Double aant = UBound(rij) Kleinste_In_Array = rij(0) For i = 1 To aant If Not (IsMissing(rij(i))) Then If rij(i) < Kleinste_In_Array Then Kleinste_In_Array = rij(i) End If End If Next i End Function Public Function ABS_Kleinste_In_Array(rij) As Double Dim i As Long Dim b As Double aant = UBound(rij) Kleinste_In_Array = rij(0) For i = 1 To aant If Not (IsMissing(rij(i))) Then If Abs(rij(i)) < Kleinste_In_Array Then Kleinste_In_Array = rij(i) End If End If Next i End Function
67
Bijlage 24
'MAAK SELECTIE SET VOLGENS EEN FILTER Public Function sst_filter(soort_filter, filter_data, Optional methode As String, Optional Lower_left As Variant, Optional Upper_right As Variant) As AcadSelectionSet On Error Resume Next Set sst_filter = ThisDrawing.SelectionSets.Add("sset1") If Err Then Set sst_filter = ThisDrawing.SelectionSets.Item("sset1") sst_filter.Clear Err.Clear End If On Error GoTo 0 methode = UCase(methode) Select Case methode Case "CROSSING" Call sst_filter.Select(acSelectionSetCrossing, Lower_left, Upper_right, soort_filter, filter_data) Case "WINDOW" Call sst_filter.Select(acSelectionSetWindow, Lower_left, Upper_right, soort_filter, filter_data) Case Else Call sst_filter.Select(acSelectionSetAll, , , soort_filter, filter_data) End Select End Function
68