示例#1
0
def process(PA):
	global ActiveWindow, Shapes, Word, TRs_all, xl, Visio
	global RESULTS
	try:

		# ouvrir le fichier excel et faire les initialisations de coutume
		xl = CreateObject("Excel.application")
		xl.Visible = False
		xl.DisplayAlerts = False
		wb = xl.Workbooks.Open(PA)
		wb.Sheets("synoptique-bilan µmodules").Select()

		# dans la sheet visée, détecter tout les objets OLE (qui seront 
		# normalement tous des déssins visio)
		OLEObjects = wb.Sheets("synoptique-bilan µmodules").OLEObjects()

		# pour chaque déssin ...
		for OLEObject in OLEObjects:
			# l'ouvrir dans Visio
			OLEObject.Verb(2)
			# prendre la main sur la fenêtre visio ouverte
			Visio = GetActiveObject("Visio.Application")
			# Visio.Visible = False
			Visio.DisplayAlerts = False
			ActiveWindow =  Visio.ActiveWindow
			Page = ActiveWindow.Page
			Shapes = Page.Shapes

			msg = "Voulez confirmer le nombre de PBs après chaque sélection?\n" \
						+ "(si c'est plan assez complexe mieux vaut répondre par oui)"
			yn = ynbox(msg)

			# allons-y!
			# On extrait d'abord les infos d'entête
			for shape in Shapes:
				text = shape.Text
				if text.startswith('NRO'):
					bloc_NRO = text
				elif text.startswith('PT'):
					try:
						blocs_PT.append(shape)
					except:
						blocs_PT = [shape]
				elif text.startswith('PA'):
					PA_posx = get_XY(shape)[0]
			if get_XY(blocs_PT[0])[0] > get_XY(blocs_PT[1])[0]:
				FI_bloc = blocs_PT[0]
				PA_bloc = blocs_PT[1]
			else:
				PA_bloc = blocs_PT[1]
				FI_bloc = blocs_PT[0]
			PA_PT = PA_bloc.Text.rsplit('\n')[0].replace('PT: ', '')
			PMZ_PT = FI_bloc.Text.rsplit('\n')[0].replace('PT: ', '')
			CH = PA_bloc.Text.rsplit('\n')[2].replace('CH: ', '')
			NRO = extract('NRO/PMZ/PA', bloc_NRO, 'NRO')
			ADRESSE1 = ' '.join(PA_bloc.Text.rsplit('\n')[3:5])\
									.replace('Adresse: ', '')
			ADRESSE2 = ADRESSE1.rsplit('-')[0]

			TRs = {}
			empty_TRs = []
			# là ça va barder!
			for shape in Shapes:
				if shape.Text.startswith('TR'):
					if get_XY(shape)[0] > PA_posx:
						TR_TXT = str(shape.Text.encode()).replace("b'", '').replace("'", '')
						TR = TR_TXT.rsplit('FO')[0] \
							.replace('\\n', ' ') + 'FO'
						if not re.match(r'TR\s+\d{2}\s+\d{4}\s+\d+FO', TR):
							empty_TRs.append(shape.ID)
							continue
						if TR not in TRs:
							TRs[TR] = {
								'LONG': 0,
								'SHAPES': [shape.ID],
								'CH/IMB/AP': [],
								'PTs': [],
								'maxPT': 0
								}
						else:
							TRs[TR]['SHAPES'].append(shape.ID)
						try:
							TR_LONG = int(TR_TXT.rsplit('\\xe2\\x80\\x93 ')[1] \
															.replace('m', ''))
						except:
							TR_LONG = 0
						TRs[TR]['LONG'] = TRs[TR]['LONG'] + TR_LONG
			
			title1 = 'Sélectionnez les bloc'
			title2 = 'Confirmez la sélection'
			for TR in TRs:
				while True:
					SelectShapes(TRs[TR]['SHAPES'])
					if ccbox(TR, title1):
						CH_OR_IMB_OR_AP_all = []
						PTs = []
						msg = "Pour " + TR + "\nVous avez sélectionné:\n"
						selected_PBs = 0
						yn_yes = True
						for selected in ActiveWindow.Selection:
							try:
								TEXT = str(selected.Text)
								if not TEXT.startswith('PB'):
									continue
								selected_PBs = selected_PBs + 1
								PT = TEXT.rsplit('\n')[2]
								ADR = TEXT.rsplit('\n')[3]
								CH_OR_IMB_OR_AP = TEXT.rsplit('\n')[4]
								if (not CH_OR_IMB_OR_AP.startswith('AP ')
										and not CH_OR_IMB_OR_AP.startswith('Ch.')
										and not CH_OR_IMB_OR_AP.startswith('IMB')):
									SelectShapes([selected.ID])
									msgbox("T'as surement encore fais une connerie dans tes"
												+ "déssins, regarde ce bloc dans la ligne PT!\n"
												+ "Je devrais trouver Ch.XXXX ou AP XXXX"
												+ "ou IMB/XXXX/XXX mais j'ai trouvé\n"
												+ CH_OR_IMB_OR_AP + "\n"
												+ "Quand t'auras détécté l'erreur click sur OK")
									cont = boolbox("Dois-je continuer ou fermer?",
																"Que faire?",
																['Continuer?', 'Fermer?'])
									if not cont:
										exit(0)
									else:
										pass
								else:
									msg = msg + "- " + CH_OR_IMB_OR_AP + "\n"
									CH_OR_IMB_OR_AP_all.append([ADR, CH_OR_IMB_OR_AP])
									PTs.append(int(PT.replace('PT', '')))
							except:
								SelectShapes([selected.ID])
								msgbox("T'as surement encore fais une connerie dans tes"
									+ "déssins, regarde ce bloc dans la ligne PT!\n"
									+ "Quand t'auras détécté l'erreur click sur OK")
								cont = boolbox("Dois-je continuer ou fermer?",
																"Que faire?",
																['Continuer?', 'Fermer?'])
								if not cont:
									exit(0)
								else:
									msg = msg + "(RIEN!)"
									CH_OR_IMB_OR_AP_all = []
									PTs = []
									yn_yes = False
						if not selected_PBs:
							cont = boolbox("Tu n'as rien sélectionné! Tu confirmes"
															+ " que ce n'est pas une connerie?",
															"Sélection vide!",
															['Oui vas-y', 'Comme d\'hab! Une connerie'])
							if cont:
								break
							else:
								continue
						if yn and yn_yes:
							msg = msg + "(" + str(selected_PBs) + " sélectionnés)"
							conf = boolbox(msg, title2, ['Confirmer?', 'Refaire?'])
							if conf:
								TRs[TR]['CH/IMB/AP'] = CH_OR_IMB_OR_AP_all
								TRs[TR]['PTs'] = PTs
								break
							else:
								pass
						else:
							TRs[TR]['CH/IMB/AP'] = CH_OR_IMB_OR_AP_all
							TRs[TR]['PTs'] = PTs
							break
					else:
						exit(0)
				if len(TRs[TR]['PTs']):
					TRs[TR]['maxPT'] = 'DE_PT%06d' % max(TRs[TR]['PTs']) + '.doc'
				else:
					TRs[TR]['maxPT'] = 'je_ne_suis_pas_cense_exister.doc'
			if TRs == {}:
				msgbox("il n'y pas de TR valide sur ce déssin")
			TRs_all.append(TRs)
			Visio.Visible = False

		RESULTS[PA] = {
			'TRs_all': 	TRs_all,
			'NRO':			NRO,
			'PMZ_PT':		PMZ_PT,
			'PA_PT':		PA_PT,
			'CH':				CH,
			'ADRESSE1':	ADRESSE1,
			'ADRESSE2':	ADRESSE2,
			'DATE':			DATE
		}
		xl.Quit()
		return

	except:
		print(format_exc())
		codebox("t'as encore fais une connerie! Fais moi un screen de malheur!",
						"Erreur",
						format_exc())
		going()
def process(PA):
	global ActiveWindow, Shapes, Word, TRs_all, xl, Visio
	global RESULTS
	# Bien gérer les erreurs
	try:

		# ouvrir le fichier excel et faire les initialisations de coutume
		xl = CreateObject("Excel.application")
		xl.Visible = False
		xl.DisplayAlerts = False
		PA_wb = xl.Workbooks.Open(PA)
		PA_wb.Sheets("synoptique-bilan µmodules").Select()

		# dans la sheet visée, détecter tout les objets OLE (qui seront 
		# normalement tous des déssins visio)
		OLEObjects = PA_wb.Sheets("synoptique-bilan µmodules").OLEObjects()

		# pour chaque déssin ...
		for OLEObject in OLEObjects:
			# l'ouvrir dans Visio
			OLEObject.Verb(2)
			# prendre la main sur la fenêtre visio ouverte
			Visio = GetActiveObject("Visio.Application")
			# Visio.Visible = False
			Visio.DisplayAlerts = False
			ActiveWindow =  Visio.ActiveWindow
			Page = ActiveWindow.Page
			Shapes = Page.Shapes
			# Ceci est pour les déssins plutôt compliqués, après chaque sélection des PB, le script
			# les affichera et demandra de confirmer si c'est bon ou non
			msg = "Voulez confirmer le nombre de PBs après chaque sélection?\n" \
						+ "(si c'est plan assez complexe mieux vaut répondre par oui)"
			yn = ynbox(msg)
			# allons-y!
			# On extrait d'abord les infos d'entête
			for shape in Shapes:
				text = shape.Text
				if text.startswith('NRO'):
					bloc_NRO = text
				elif text.startswith('PT'):
					# certaines shapes buguent je ne sais pas pourquoi, elles n'ont pas d'utilité
					try:
						blocs_PT.append(shape)
					except:
						blocs_PT = [shape]
				elif text.startswith('PA'):
					bloc_PA = text
					# On extrait la position x du PA pour prendre toutes les TR qui sont à droite
					PA_posx = get_XY(shape)[0]
			# Les deux blocs FI et PA tout deux commencent par PT, celui de PA est plus à gauche
			# on les différenciera par leur position
			if get_XY(blocs_PT[0])[0] < get_XY(blocs_PT[1])[0]:
				FI_bloc = blocs_PT[0]
				PA_bloc = blocs_PT[1]
			else:
				FI_bloc = blocs_PT[1]
				PA_bloc = blocs_PT[0]

			PA_PT = PA_bloc.Text.rsplit('\n')[0].replace('PT: ', '')
			PMZ_PT = FI_bloc.Text.rsplit('\n')[0].replace('PT: ', '')
			CH = PA_bloc.Text.rsplit('\n')[2].replace('CH: ', '')
			NRO = extract('NRO/PMZ/PA', bloc_NRO, 'NRO')
			ADRESSE1 = ' '.join(PA_bloc.Text.rsplit('\n')[3:5])\
									.replace('Adresse: ', '')
			ADRESSE2 = ADRESSE1.rsplit('-')[0]

			# Les TRs du déssin courant
			TRs = {}

			# là ça va barder!
			for shape in Shapes:
				if shape.Text.startswith('TR'):
					# Seulement ceux qui sont plus à droite de PA
					if get_XY(shape)[0] > PA_posx:
						# Le text est un peu bizarre, il est vraiment en texte mais paraît être un
						# bytes! On doit le nettoyer
						TR_TXT = str(shape.Text.encode()).replace("b'", '').replace("'", '')
						# Extraire ne TR
						TR = TR_TXT.rsplit('FO')[0] \
							.replace('\\n', ' ') + 'FO'
						# Si ce n'est pas un TR valide, passer
						if not re.match(r'TR\s+\d{2}\s+\d{4}\s+\d+FO', TR):
							continue
						# Si ce TR n'a pas encore été enregistré dans la liste TRs, l'enregistrer
						## Initialiser la longueur à 0
						## Mettre le shape courant dans la liste "shapes"
						## Initialiser une liste vide pour les CH ou IMB ou AP qui vont avec
						## Initialiser une liste vide pour les PTs qui vont avec (pour le nommage)
						## Et initialiser une variable "0" pour le PT qui est maximum (pour le nommage)
						if TR not in TRs:
							TRs[TR] = {
								'LONG': 0,
								'SHAPES': [shape.ID],
								'CH/IMB/AP': [],
								'PTs': [],
								'maxPT': 0
								}
						# Sinon si le TR est déjà dans TRs, ajouter le shape courant à "SHAPES"
						else:
							TRs[TR]['SHAPES'].append(shape.ID)
						# Essayer d'extraire la longueur du TR courant
						try:
							TR_LONG = int(TR_TXT.rsplit('\\xe2\\x80\\x93 ')[1] \
															.replace('m', ''))
						except:
							TR_LONG = 0
						# Et incrémenter la longueur du TR global corréspondant à cette ligne
						TRs[TR]['LONG'] = TRs[TR]['LONG'] + TR_LONG
			
			# Message pour que l'utilisateur sélectionner les blocs PB pour chaque TR
			title1 = 'Sélectionnez les bloc'
			title2 = 'Confirmez la sélection'
			# Pour chaque TR dans TRs
			for TR in TRs:
				# Python n'a pas de "REDO", on hack avec un "WHILE"
				while True:
					# Sélectionner toutes les shapes de cette ligne de TR
					SelectShapes(TRs[TR]['SHAPES'])
					# Demander lui de sélectionner, quand il confirme continuer...
					if ccbox(TR, title1):
						# Une liste vide pour tout les PB dans ce TR
						CH_OR_IMB_OR_AP_all = []
						# Une liste vide pour tout les PTs dans ce TR
						PTs = []
						# Une liste vide pour tout les PBs dans ce TR
						PBs = []
						# Un message au cas où l'utilisateur aurait choisit une confirmation
						msg = "Pour " + TR + "\nVous avez sélectionné:\n"
						# Le nombre de PBs sélectionnées (pour affichage dans la confirmation)
						selected_PBs = 0
						# Au cas où il n'y aurait pas de PB valide, pas la peine de mettre une 
						# fenêtre de confirmation, supposer tout de même qu'il y'en a ...
						yn_yes = True
						# Pour chaque fenêtre sélectionnée
						for selected in ActiveWindow.Selection:
							# (certains shapes n'aiment pas qu'on appelle leur .Text!!!!)
							try:
								TEXT = str(selected.Text)
								# Prendre seulement les blocs qui commencent par "PB"
								if not TEXT.startswith('PB'):
									continue
								# Incrémenter le nombre de PBs trouvés par +1
								selected_PBs = selected_PBs + 1
								# Enregister le PB, PT, l'adresse, et le text qui peut être un:
								## Ch.XXXXX
								## IMB/XXXXX/XXXX
								## AP XXXX
								PB = TEXT.rsplit('\n')[0].rstrip()
								PT = TEXT.rsplit('\n')[2]
								ADR = TEXT.rsplit('\n')[3]
								CH_OR_IMB_OR_AP = TEXT.rsplit('\n')[4]
								# Si l'un de ces lignes ne se trouve pas à la bonne place
								if (not CH_OR_IMB_OR_AP.startswith('AP ')
									and not CH_OR_IMB_OR_AP.startswith('Ch.')
									and not CH_OR_IMB_OR_AP.startswith('IMB')):
									# Resélectionner les sélectionnés (pfff sert à rien ça!)
									SelectShapes([selected.ID])
									# Et dire qu'il y a un truc qui cloche!
									msgbox("T'as surement encore fais une connerie dans tes"
												+ "déssins, regarde ce bloc dans la ligne PT!\n"
												+ "Je devrais trouver Ch.XXXX ou AP XXXX"
												+ "ou IMB/XXXX/XXX mais j'ai trouvé\n"
												+ CH_OR_IMB_OR_AP + "\n"
												+ "Quand t'auras détécté l'erreur click sur OK")
									# Continuer ou quitter!
									cont = boolbox("Dois-je continuer ou fermer?",
																"Que faire?",
																['Continuer?', 'Fermer?'])
									if not cont:
										exit(0)
									else:
										pass
								else:
									# Sinon, préparer le message de confirmation
									msg = msg + "- " + CH_OR_IMB_OR_AP + "\n"
									# Et ajouter le CH/IMB/AP à la liste
									CH_OR_IMB_OR_AP_all.append([ADR, CH_OR_IMB_OR_AP])
									# Ajouter le PT de ce bloc à la liste PTs
									PTs.append(int(PT.replace('PT', '')))
									# Ajouter le PB de ce bloc à la liste PBs
									PBs.append(PB)
							except:
								# Si quelque chose cloche, trouver une porte de sortie!!:
								SelectShapes([selected.ID])
								msgbox("T'as surement encore fais une connerie dans tes"
										+ "déssins, regarde ce bloc dans la ligne PT!\n"
										+ "Quand t'auras détécté l'erreur click sur OK")
								cont = boolbox("Dois-je continuer ou fermer?",
												"Que faire?",
												['Continuer?', 'Fermer?'])
								# Vraiment je ne sais pas à quoi sert ce que j'ai écrit dans les 
								# 8 prochaines lignes!!!!
								if not cont:
									exit(0)
								else:
									msg = msg + "(RIEN!)"
									CH_OR_IMB_OR_AP_all = []
									PTs = []
									PBs = []
									yn_yes = False
						# S'il n'a rien sélectionné
						if not selected_PBs:
							cont = boolbox("Tu n'as rien sélectionné! Tu confirmes"
											+ " que ce n'est pas une connerie?",
											"Sélection vide!",
											['Oui vas-y', 'Comme d\'hab! Une connerie'])
							# Soit on quitte!
							if cont:
								break
							# Soit c'est délibéré et on continue
							else:
								continue

						# Si l'utilisateur avait demandé une confirmation, la montrer
						# (S'il y a eu une erreur, yn_yes est False, et pas la peine de montrer la
						# confirmation)
						if yn and yn_yes:
							msg = msg + "(" + str(selected_PBs) + " sélectionnés)"
							conf = boolbox(msg, title2, ['Confirmer?', 'Refaire?'])
							if conf:
								# Si c'est confirmé, stocher ces données pour le shape
								TRs[TR]['CH/IMB/AP'] = CH_OR_IMB_OR_AP_all
								TRs[TR]['PTs'] = PTs
								TRs[TR]['PBs'] = PBs
								break
							else:
								pass
						# Sinon s'il n'avait pas demandé de confirmation, stocker ces données
						# directement pour le shape
						else:
							TRs[TR]['CH/IMB/AP'] = CH_OR_IMB_OR_AP_all
							TRs[TR]['PTs'] = PTs
							TRs[TR]['PBs'] = PBs
							break
					# En cas d'erreur sortir :-(
					else:
						exit(0)
				# Il doit y avoir au moins un PT pour créer un fichier doc et xls avec le max des TRs
				if len(TRs[TR]['PTs']):
					TRs[TR]['DE_filename'] = 'DE_PT%06d' % max(TRs[TR]['PTs']) + '.doc'
					TRs[TR]['AR_filename'] = 'AR_PT%06d' % max(TRs[TR]['PTs']) + '.xls'
				# Les fichiers avec ce nom ne devront jamais voir le jour!
				else:
					TRs[TR]['DE_filename'] = 'je_ne_suis_pas_cense_exister.doc'
					TRs[TR]['AR_filename'] = 'je_ne_suis_pas_cense_exister.xls'
					# Un cas très particulier m'a forcé à ajourer la ligne suivant!
					TRs[TR]['PBs'] = []

			# Si je n'ai trouvé aucun TR, montrer un message
			if TRs == {}:
				msgbox("il n'y pas de TR valide sur ce déssin")
			# Ajouter ces TRs à TR_all
			TRs_all.append(TRs)
			# Cacher le déssin Visio
			Visio.Visible = False

		# Demander qui est le client
		xl.Visible = True
		msg = "Quel est le client pour cette fiche PA?"
		choices = ["Circet","Engie"]
		client = buttonbox(msg, choices=choices)

		# Résultat globaux pour cette fiche PA
		RESULTS[PA] = {
			'PA_REF':		bloc_PA,
			'client':		client,
			'TRs_all': 		TRs_all,
			'NRO':			NRO,
			'PMZ_PT':		PMZ_PT,
			'PA_PT':		PA_PT,
			'CH':			CH,
			'ADRESSE1':		ADRESSE1,
			'ADRESSE2':		ADRESSE2,
			'DATE':			DATE
		}

		# Quitter excel et passer à la prochaine fiche PA
		xl.Quit()
		return

	except:
		# En cas d'erreur innatendue!
		print(format_exc())
		codebox("t'as encore fais une connerie! Fais moi un screen de malheur!",
				"Erreur",
				format_exc())
		going()