Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour à tous, j'aimerai pouvoir protéger uniquement certaines cellules sur mon document Excel.
En fait je veux uniquement pouvoir modifier le contenu des cellules en colonne K, et protéger les autres, et ce, de la 1ère ligne à la dernière ligne.
Je travaille sous PB 10 et Excel 2000.
Ci-desous mon code actuel, le fait de changer le titre de la colonne en "activité" fonctionne parfaitement, par contre le reste non.
// Exemple Nomenclature nom de fichier justificatif : JUST_expl987987_20090928_122536.xls ls_file = "JUST_"+is_filename[ll_fichier]+"_"+String(Today(), "YYYYMMDD_HHMMSS")+".xls" this.ids_rapport.saveas("c:\FH\Justificatifs\"+ls_file, Excel!, true) li_rtn = lole_excel.ConnectToNewObject("excel.application") if li_rtn <> 0 then MessageBox( "Error", 'Error running MS Excel api.') destroy lole_Excel else lole_excel.WorkBooks.Open("C:\FH\Justificatifs\"+ls_file+".xls") // Set the cell value lole_excel.application.workbooks(1).worksheets(1).cells(1,11).value = "Activité" ls_range = "A1:F"+string(ll_excel_rows) lole_excel.application.workbooks(1).worksheets(1).Range(ls_range).Select lole_excel.application.workbooks(1).worksheets(1).Range(ls_range).Locked = True ls_range = "H1:K"+string(ll_excel_rows) lole_excel.application.workbooks(1).worksheets(1).Range(ls_range).Select lole_excel.application.workbooks(1).worksheets(1).Range(ls_range).Locked = True // Save lole_excel.application.workbooks(1).save() // Quit lole_excel.application.quit() lole_excel.DisconnectObject() destroy lole_excel end if
J'aimerai également pouvoir changer la couleur de fond de la colonne K, mais je ne trouve par la syntaxe.
Merci d'avance
Dernière modification par johnpelu (07-09-2009 13:31:08)
Hors ligne
Bonjour,
Pour les couleurs de fond de colonne:
lole_excel.Selection.Interior.ColorIndex = 15
Sinon, essaye ceci pour locker tes colonnes:
lole_excel.application.workbooks(1).worksheets(1).Range(ls_range).Select lole_excel.selection.Locked = True
Si ça ne marche toujours pas, il te faudra décomposer ta sélection en passant par un objet ole_range.
Hors ligne
Bonjour Foon, j'ai bien essayé ton code mais cela ne fonctionne pas.
Peux-tu m'expliquer comment utiliser un ole_range car je ne connais rien du tout concernant l'utilisation des OLE.
D'avance merci de ton aide
Hors ligne
Bonjour johnpelu,
Pour faciliter mes opérations sous Excel, je défini en général 3 objets OLE:
- Un pour gérer l'application Excel proprement dite
- Un pour gérer la sheet Excel courante
- Un pour gérer le range de cellules à sélectionner
Long ll_result OleObject lole_OLE, lole_Sheet, lole_Range lole_OLE = CREATE OleObject // Ouvre l'application Excel (en arrière plan) ll_result =lole_OLE.ConnectToNewObject( 'excel.application' ) if ll_result = 0 then // Ajout d'un classeur Excel lole_OLE.Workbooks.Add GarbageCollect ( ) // Sélectionne la première feuille Excel lole_sheet = lole_OLE.Application.ActiveWorkbook.WorkSheets[1] GarbageCollect ( ) //Range à sélectionner ls_rangecol = '"A1:F1" lole_range = lole_sheet.Range( ls_rangecol ) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) //Met en caractères gras la sélection: lole_OLE.Selection.Font.Bold = True GarbageCollect ( ) //Sauvegarde du fichier lole_OLE.Application.ActiveWorkbook.SaveAs("C:\Test.xls") GarbageCollect ( ) // Ferme le classeur en cours lole_OLE.Application.ActiveWorkbook.Close GarbageCollect ( ) // Quitte l'application Excel lole_OLE.Application.Quit() GarbageCollect ( ) lole_OLE.DisconnectObject() DESTROY lole_OLE end if
NB: Note l'utilisation systématique du GarbageCollector afin de vider la mémoire après chaque instruction Excel
Hors ligne
L'avantage d'utiliser un ole_range, c'est que tu peux concaténer tes sélection par l'utilisation de l'instruction "union" de Excel.
Ca permet de sélectionner plusieurs plages de cellules discontinues dans ta sheet courante en une seule fois:
OleObject lole_range String ls_rangetoken ls_rangetoken = "A1:F1,B2:F2" ls_rangecol = "" ls_range = "" DO WHILE Len( ls_rangetoken ) > 0 ls_rangecol = lnv_string.of_gettoken( ls_rangetoken, ",") IF Len( ls_rangecol ) > 0 THEN IF Len( ls_range ) > 0 THEN ls_range = ls_range + ls_rangecol lole_range = a_ole_ole.Application.Union(lole_range, a_ole_sheet.Range(ls_rangecol)) GarbageCollect ( ) ELSE ls_range = ls_rangecol lole_range = a_ole_sheet.Range( ls_rangecol ) GarbageCollect ( ) END IF END IF LOOP
Hors ligne
J'ai essayé d'utiliser tes informations, j'arrive toujours à changer l'intitulé de ma colonneen "Activité", à mettre la première ligne de la colonne G en jaune (mais pas le reste malheureusement), mais les cellus de A à F et de H à K ne sont pas verrouillées, ai-je oublié quelque chose ?
li_rtn = lole_OLE.ConnectToNewObject("excel.application") if li_rtn <> 0 then return "Erreur" destroy lole_OLE else // lole_excel.WorkBooks.Open("C:\FH\Justificatifs\"+ls_file+".xls") lole_OLE.WorkBooks.Open("C:\FH\Erreur\test.xls") // Ajout d'un classeur Excel // lole_OLE.Workbooks.Add // GarbageCollect ( ) // Set the cell value lole_OLE.application.workbooks(1).worksheets(1).cells(1,11).value = "Activité" // Sélectionne la première feuille Excel lole_sheet = lole_OLE.Application.ActiveWorkbook.WorkSheets[1] GarbageCollect ( ) //Range à sélectionner ls_range = "A1:F"+string(ll_excel_rows) lole_range = lole_sheet.Range( ls_range) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) lole_OLE.selection.Locked = True //Range à sélectionner ls_range = "H1:K"+string(ll_excel_rows) lole_range = lole_sheet.Range( ls_range) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) lole_OLE.selection.Locked = True //Range à sélectionner ls_range = "G1:G"+string(ll_excel_rows) lole_range = lole_sheet.Range(ls_range) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) lole_OLE.Selection.Interior.ColorIndex = 6 // Save lole_OLE.application.workbooks(1).save() // Ferme le classeur en cours lole_OLE.Application.ActiveWorkbook.Close GarbageCollect ( ) // Quitte l'application Excel lole_OLE.Application.Quit() GarbageCollect ( ) lole_OLE.DisconnectObject() destroy lole_OLE return ls_file
Hors ligne
Tu as vérifié la valeur de ll_excel_rows?
Je ne vois pas traces de l'initialisation.
Hors ligne
je n'ai pas tout mis mais elle est initialisée comme suit:
ll_excel_rows = il_row_rapport[ll_fichier] + 1
Mais je vais passer en debug pour en être sur
Hors ligne
Essaye en mettant une valeur en dur, pour vérifier si la sélection de la plage de cellules fonctionne.
N'oublies pas non plus que le nombre de lignes max est limité à 65536 dans les versions Excel antérieures à Excel 2007.
(D'ailleurs, il serait intéressant que tu communiques ta version d'Excel)
Hors ligne
Salut Foon, je l'ai mentionnée dans le premier post, il s'afit d'un Excel 2000.
Alors j'ai effectué un test complet et correct (dynamique).
concernant la colonne jaune, aucun souci ca marche nickel, par contre en ce qui concerne la protection de cellule ca ne fonctionne pas.
voici le code complet de ma fonction:
Long ll_i Long ll_row Long ll_fichier Long ll_excel_rows String ls_id_activite String ls_file String ls_range String ls_temp Integer li_rtn Datastore lds_activite OleObject lole_OLE OleObject lole_Sheet OleObject lole_Range lole_OLE = CREATE OLEObject //Datastore contenant l'ensemble des activités lds_activite = create datastore lds_activite.dataobject = "dw_activite_gd" lds_activite.settransobject( SQLCA) lds_activite.retrieve( ) ll_fichier = this.tab_fh.tabpage_import.dw_fichier_harmonise.getrow( ) if ll_fichier = 1 then ll_row = 1 else ll_row = il_row_rapport[ll_fichier] - il_row_rapport[ll_fichier - 1] end if ll_excel_rows = il_row_rapport[ll_fichier] + 1 for ll_i = ll_row to (il_row_rapport[ll_fichier] - 1) // On récupère le numéro de ligne, ensuite on récupère la variable pour cette ligne ls_id_activite = String(ids_copie_exploit_cptbl.object.id_activite[ids_rapport.object.nrligne[ll_i]]) lds_activite.setfilter( "id_activite ="+ ls_id_activite) lds_activite.filter( ) if lds_activite.rowcount( ) > 0 then // On utilise le champ critere_valeur pour y stocker la variable, utilisé uniquement pour l'export en Excel, non enregistré en base ids_rapport.object.critere_valeur[ll_i] = lds_activite.object.libelle_activite[1] end if next ls_temp = mid(is_filename[ll_fichier], 1, (len(is_filename[ll_fichier]) - 4)) // Exemple Nomenclature nom de fichier justificatif : JUST_expl987987_20090928_122536.xls ls_file = "JUST_"+ls_temp+"_"+String(Today(), "YYYYMMDD_HHMMSS")+".xls" this.ids_rapport.saveas("C:\FH\Justificatifs\"+ls_file, Excel8!, true) li_rtn = lole_OLE.ConnectToNewObject("excel.application") if li_rtn <> 0 then return "Erreur" destroy lole_OLE else lole_OLE.WorkBooks.Open("C:\FH\Justificatifs\"+ls_file) // lole_OLE.WorkBooks.Open("C:\FH\Erreur\test.xls") // Set the cell value lole_OLE.application.workbooks(1).worksheets(1).cells(1,11).value = "Activité" // Sélectionne la première feuille Excel lole_sheet = lole_OLE.Application.ActiveWorkbook.WorkSheets[1] GarbageCollect ( ) //Range à sélectionner ls_range = "A1:F"+string(ll_excel_rows) lole_range = lole_sheet.Range( ls_range) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) lole_OLE.selection.Locked = True //Range à sélectionner ls_range = "H1:K"+string(ll_excel_rows) lole_range = lole_sheet.Range( ls_range) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) lole_OLE.selection.Locked = True //Range à sélectionner ls_range = "G1:G"+string(ll_excel_rows) lole_range = lole_sheet.Range(ls_range) GarbageCollect ( ) lole_range.Select GarbageCollect ( ) lole_OLE.Selection.Interior.ColorIndex = 27 // Save lole_OLE.application.workbooks(1).save() ////////////////////// // Ferme le classeur en cours lole_OLE.Application.ActiveWorkbook.Close GarbageCollect ( ) // Quitte l'application Excel lole_OLE.Application.Quit() GarbageCollect ( ) lole_OLE.DisconnectObject() destroy lole_OLE return ls_file end if
Tant que j'y suis, il y a t'il une possiblité d'ajuster automatiquement la largeur des colonnes?
Dernière modification par johnpelu (07-09-2009 09:34:38)
Hors ligne
Pour info, pour trouver facilement le code VBA à exécuter, il suffit d'enregistrer une macro en effectuant les opérations "à la main" puis de regarder le code VBA généré...
Hors ligne
En fait, le verrouilalge de cellule fonctionne, mais je viens de lire qu'apparemment il est totalement inutile s'il n'est pas combiné avec la protection de la feuille.
Il n'y a pas moyen de protéger uniquement certaines cellules? Mon but est de permettre à l'utilisateur uniquement la modification sur la colonne G, et verrouiller/protéger les autres.
Hors ligne
Pour info, la commande pour le resize auto des colonnes, c'est:
lole_OLE.Selection.Columns.AutoFit
Hors ligne
Merci Foon, et en ce qui concerne la protection, peux-tu m'en dire plus ?
Hors ligne
johnpelu a écrit:
Merci Foon, et en ce qui concerne la protection, peux-tu m'en dire plus ?
Malheureusement non. Il faut effectivement que la protection de la feuille Excel soit activée pour que les cellules soient
protégées. Cependant, regarde sur les forums spécialisés sur les développements VB sous Excel, il y aura peut-être une astuce à trouver.
Hors ligne
Merci, c'est un peu con car même les cellules non verrouillées sont protégées dans ce cas mdr.
Encore une fois, je te remercie et cloture donc ce sujet.
Hors ligne
johnpelu a écrit:
Merci, c'est un peu con car même les cellules non verrouillées sont protégées dans ce cas mdr.
bah non sinon quel en serait l'intérêt ?
Lorsque votre tableau comporte des zones de saisie et des zones de calcul, il est important de le protéger pour exploitation par des tierces personnes. Lorsque vous saisissez un texte sur une cellule de calcul, vous effacez tout simplement la formule. Un classeur peut très vite être déterioré.
Principe assez déroutant dans la notion de protection d'Excel, toutes les cellules d'une feuille sont verrouillées par défaut. Pour preuve :
- Réalisez un clic droit sur une ou plusieurs cellules,
- Dans le menu contextuel, cliquez sur Format de cellule,
- Dans la boîte de dialogue, activez l'onglet protection,
Vous remarquez que la case Verrouillée est cochée. Pourtant rien ne nous empêche de saisir dedans ou encore de changer les couleurs. En effet, Verrouillée est un état qui prend effet à partir du moment où vous protégez la feuille.Si vous protégez la feuille maintenant, toutes les cellules seront verrouillées contre la saisie.
En somme, avant de protéger une feuille Excel, il convient de déverrouiller les cellules que vous souhaitez laisser libre à la saisie et de protéger la feuille ensuite. Ainsi après protection seules ces cellules pourront être modifiées.
.
johnpelu a écrit:
Encore une fois, je te remercie et cloture donc ce sujet.
en majuscules le RESOLU, stp
Hors ligne
erasorz a écrit:
johnpelu a écrit:
Merci, c'est un peu con car même les cellules non verrouillées sont protégées dans ce cas mdr.
bah non sinon quel en serait l'intérêt ?
Lorsque votre tableau comporte des zones de saisie et des zones de calcul, il est important de le protéger pour exploitation par des tierces personnes. Lorsque vous saisissez un texte sur une cellule de calcul, vous effacez tout simplement la formule. Un classeur peut très vite être déterioré.
Principe assez déroutant dans la notion de protection d'Excel, toutes les cellules d'une feuille sont verrouillées par défaut. Pour preuve :
- Réalisez un clic droit sur une ou plusieurs cellules,
- Dans le menu contextuel, cliquez sur Format de cellule,
- Dans la boîte de dialogue, activez l'onglet protection,
Vous remarquez que la case Verrouillée est cochée. Pourtant rien ne nous empêche de saisir dedans ou encore de changer les couleurs. En effet, Verrouillée est un état qui prend effet à partir du moment où vous protégez la feuille. Si vous protégez la feuille maintenant, toutes les cellules seront verrouillées contre la saisie.
En somme, avant de protéger une feuille Excel, il convient de déverrouiller les cellules que vous souhaitez laisser libre à la saisie et de protéger la feuille ensuite. Ainsi après protection seules ces cellules pourront être modifiées..
johnpelu a écrit:
Encore une fois, je te remercie et cloture donc ce sujet.
en majuscules le RESOLU, stp
Je revenais justement our dire que je venais de trouver la solution...
Merci à tous
Hors ligne
lors de la souvegarde de mon fichier xls j'ai le message suivant : il demande de convertir la feuil excel 2.1 voulez vous le convertirce fichier un nouveau formt
comment ouvrir le fichier avec le nouveau format dans un OLE Xls. ?
iole_excel = CREATE oleobject
iole_excel.ConnectToNewObject("excel.application")
iole_excel.Application.Workbooks.Open(as_filename )
iole_excel.Cells.Select
iole_excel.Cells.EntireColumn.AutoFit
// iole_excel.Applicatio.HorizontalAlignment (xlCenter).Rang("C2:M3")
// iole_excel.Application.Selection.Merge
//iole_excel.Application.Range("C2:N3").Select
iole_excel.Sheets(1).Select()
iole_excel.Sheets(1).Select()
iole_excel.Application.Range("C2").Select()
iole_excel.Application.Range("C2:N3").Select
iole_excel.Application.selection.Locked = True
//iole_excel.Application.Cells.HorizontalAlignment ( xlCenter)
si quand je merge les celules.
iole_excel.Application.Selection.Merge
GarbageCollect ( )
iole_excel.Application.DisplayAlerts = true
iole_excel.ActiveWorkbook.Save()
// Ferme le classeur en cours
iole_excel.Application.ActiveWorkbook.Close
GarbageCollect ( )
merci d'avance
Hors ligne
Bonjour,
Merci d'ouvrir un nouveau topic, et
Cordialement.
Hors ligne
Bonjour à tous,
J'ai voulu savoir comment affecter une liste de valeur à un range!
En effet, j'aimerai ,par exemple,remplir un range(A1:A3) par les valeurs {val1,val2,val3}?
Merci pour vos réponses
Hors ligne
kkarmi a écrit:
Bonjour à tous,
J'ai voulu savoir comment affecter une liste de valeur à un range!
En effet, j'aimerai ,par exemple,remplir un range(A1:A3) par les valeurs {val1,val2,val3}?
Merci pour vos réponses
Bonjour merci de créer un nouveau message.
Hors ligne