Suite

Champs d'attribut à incrémentation automatique à l'aide de curseurs ArcPy et d'instructions conditionnelles ?


J'essaie de créer des identifiants uniques pour un attribut nommé "FACILITYID" (str) et j'ai reçu une tonne d'aide de publications connexes et de didacticiels python en ligne. J'ai sélectionné les lignes pour lesquelles je souhaitais créer des identifiants uniques et j'ai utilisé cette fonction autoIncrement () dans le calculateur de champ qui fonctionne bien.

def autoIncrement(pStart=1,pInterval=1): global rec if (rec == 0): rec = pStart return rec else: rec = rec + pInterval return rec

Cependant, je voudrais garder une trace de la variable rec afin que je puisse créer de nouveaux identifiants uniques plus tard. Après avoir conclu que je devais sortir de la calculatrice de champ, j'ai essayé d'utiliser des curseurs à la place.

Pour mettre à jour la valeur d'ID maximale, j'ai créé une table de données dans l'environnement avec un seul attribut "FACILITYID" qui peut être mis à jour lors de l'exécution du code. J'ai eu du succès avec cela à l'exception d'un petit détail : je veux seulement mettre à jour les lignes qui n'ont pas déjà un FacilityID. Plus précisément, je veux seulement que le code fonctionne pour les lignes avec le FACILITYID est égal à un caractère d'espace.

ID FACILITÉ =="

J'ai essayé d'innombrables instructions if, des boucles while, la fonction getValue() et plus encore, mais je n'arrive pas à bien faire les choses. Quelqu'un peut-il m'aider à faire fonctionner ce code pour mes champs d'attribut cibles ?

#import modules import os, sys import arcpy #Set variables rec = 0 workspace = "Database ConnectionsFE.sde" arcpy.env.workspace = workspace feature_name = "FE.SManhole" #change feature class if required field = "FACILITYID" table_name = "FE.SWR_FacilityID" tRows = arcpy.SearchCursor(table_name) tRow = tRows.next() #Tirer la valeur la plus élevée actuelle de la table Facility_ID maxID = int(tRow.getValue(field)) # définir la fonction d'incrémentation automatique def autoIncrement (pStart=maxID,pInterval=1) : global rec if (rec == 0) : rec = pStart return rec else : rec = rec + pInterval return rec #boucle dans la table pour mettre à jour FacilityID si nécessaire. curseur = arcpy.UpdateCursor(feature_name) #Il n'y a aucune garantie d'ordre ici pour la ligne dans le curseur : #####emplacement où j'ai essayé les instructions if.#### row.setValue(field, str(autoIncrement() )) cursor.updateRow(row) #save new rec value to FE.SWR_FacilityID table maxID = rec tRows = arcpy.UpdateCursor(table_name) tRow = tRows.next() tRow.setValue(field, str(maxID)) tRows.updateRow (tRow) del tRows, tRow, cursor, row print 'Valeur "FACILITYID" la plus élevée : ' + str(maxID)

Je suis très nouveau sur python et j'ai obtenu la majorité de ce code à partir de messages précédents, y compris l'incrémentation automatique dans le script Python avec le curseur ArcPy ?


La fonction que vous utilisez pour incrémenter automatiquement les ID est destinée à être utilisée dans la calculatrice de champ ; dans le calculateur de champs, vous devez définir la variable globale à utiliser par les autres lignes du tableau, sinon toutes vos valeurs seraient 1. Pour vos besoins, vous devez nécessairement définir rec comme variable globale, et vous n'avez pas besoin pour créer une fonction pour ajouter 1 (il suffit d'utiliserenr+=1).

Problème : Vous avez un tableau des installations, certaines installations ont déjà des identifiants et d'autres pas. L'ID est une valeur numérique qui est stockée dans un champ de texte, vous devez donc trouver le plus grand numéro d'ID déjà attribué et garder une trace du plus grand ID que votre script a attribué. Je suppose que vous ne voulez pas attribuer automatiquement un ID déjà attribué à une autre ligne (faisant ainsi de votre champ une clé primaire).

Avec un curseur arcpy.da, vous pouvez avoir une requête (clause where) intégrée au curseur, de sorte que vous parcourez uniquement les lignes qui satisfont aux conditions de la requête (http://desktop.arcgis.com/en/arcmap /10.3/analyze/arcpy-data-access/updatecursor-class.htm) . Essaye ça:

import os, sys import arcpy #Set variables rec = 0 workspace = "Database ConnectionsFE.sde" arcpy.env.workspace = workspace feature_name = "FE.SManhole" #change feature class if required field = ["FACILITYID"] table_name = "FE.SWR_FacilityID" ### Créer une liste de tous les ID d'installation déjà renseignés ### convertir chaque élément en entier, si l'élément n'est pas"ou"ou Aucun ###### Je suppose que votre les identifiants sont des entiers, mais vous devrez peut-être changer ceci all_facility_ids = [int(x[0]) pour x dans arcpy.da.SearchCursor(feature_name, field) if x[0] pas dans [",", None]] # ## Trier la liste des identifiants (du plus petit au plus grand) et renvoyer le dernier élément max_id = trié(all_facility_ids)[-1] #boucler les données avec arcpy.da.UpdateCursor (beaucoup plus rapide) # les curseurs arcpy.da ont la possibilité de utiliser une requête, nous allons donc faire cette requête = "FACILITYID not in (",", NULL)" avec arcpy.da.UpdateCursor(feature_name, field, query) comme curseur : pour la ligne dans le curseur : tandis que True : ## Cette partie continuera à s'ajouter à rec si le numéro est déjà dans th e liste des identifiants d'installation if rec in all_facility_ids: rec +=1 else: rec +=1 break row[0] = str(rec) cursor.updateRow(row) del cursor

Voici une autre option, si vous souhaitez utiliser une instruction if pour parcourir toutes les lignes :

avec arcpy.da.UpdateCursor(feature_name, field) comme curseur : pour la ligne dans le curseur : si la ligne[0] n'est pas dans (",", Aucun) : tandis que True : ## Cette partie continuera à s'ajouter à rec si le nombre est déjà dans la liste des identifiants d'installation if rec in all_facility_ids: rec +=1 else: rec +=1 break row[0] = str(rec) cursor.updateRow(row) else: continue del cursor

Le MLE conditionnel pour un modèle auto-régressif peut être résolu en utilisant la théorie de régression linéaire standard. Il est facile de le faire sous forme matricielle et d'utiliser la formule standard pour l'estimateur de coefficient sous cette forme. Néanmoins, il est possible de résoudre le problème de maximisation sous forme scalaire, et je vais vous montrer comment faire.

Votre sommation dans cette probabilité conditionnelle est mal écrite. Je suppose que vous avez observé des valeurs de temps $t = 1, 2, . T$, auquel cas on conditionne sur les valeurs $t = 1, 2$ et la sommation part de $t = 3, . T$. C'est aussi plus simple si vous écrivez vos équations en fonction du paramètre de précision $lambda equiv sigma^<-2>$. Avec ces changements, et une simplification supplémentaire de la suppression des constantes additives, la fonction de log-vraisemblance conditionnelle peut être écrite comme :

$ell (phi_1, phi_2, lambda) = frac <2>cdot ln (lambda) - frac <2>sum_^T (x_t - phi_1 x_ - phi_2 x_)^2.$

Pour faciliter notre analyse, nous définissons les quantités d'échantillon $s_ equiv somme_^T x_ X_$ pour $i,j = 0, 1, 2$. En utilisant cette notation, les fonctions de score sont :

Coefficients d'auto-régression : Les MLE conditionnelles pour les coefficients auto-régressifs résolvent les équations simultanées :

La résolution de ces équations donne :

Paramètre d'écart/précision : La MLE conditionnelle pour la variance/précision est obtenue en mettant la première des équations de score à zéro et en substituant les estimateurs aux coefficients autorégressifs. Il est donné par :

Il s'agit d'un estimateur biaisé, et la correction de Bessel est généralement appliquée pour corriger cela, en substituant $T-3$ au dénominateur au lieu de $T-2$.


Comment puis-je rendre dynamiquement les champs requis à l'aide d'un composant dynamique

J'ai une page Visualforce sur laquelle je rends beaucoup de champs à l'aide d'un composant dynamique (qui est un panneau de sortie qui contient tous les champs). Les champs sont ajoutés en fonction d'une sélection d'options dans une liste multipick, et chaque fois qu'une sélection est effectuée dans la liste multipick, la page est restituée du côté serveur pour afficher la nouvelle sélection de champs. Certains de ces champs doivent être obligatoires.

Chaque fois qu'un champ est requis sur la page et que la sélection est modifiée dans la liste de sélection multiple qui contrôle quels champs sont affichés, Visualforce renvoie une erreur indiquant que le champ n'a pas été rempli, même s'il doit être supprimé en fonction de la sélection. Cela empêche la suppression du champ et les champs de la page ne sont pas mis à jour en raison de cette erreur Visualforce.

J'ai donc eu l'idée de créer ma propre fonctionnalité requise en utilisant jQuery et JavaScript pour valider côté client avec une méthode de validation dans Apex côté serveur.

Y a-t-il une meilleure manière de faire cela? Sinon, comment puis-je dupliquer la fonctionnalité "requise" de Visualforce (affichage d'une barre rouge à côté de chacun des champs obligatoires).

Pour référence

Voici une partie de ma page Visualforce actuelle. Produits est une liste de sélection multiple à chaque fois que l'on clique sur le bouton de commande, les champs sont restitués.

La méthode SelectProduct est extrêmement simple. C'est juste une méthode qui ne fait rien et ne retourne rien. Il est principalement utilisé pour effectuer un aller-retour vers le serveur pour restituer la propriété SectionsAndFields. Pour un exemple de code de la propriété SectionsAndFields, consultez cette réponse à une autre question.


Ajoutez un attribut onchange à l'apex:inputField (Field1) qui appelle une fonction JavaScript lorsque Field1 est modifié pour évaluer la valeur souhaitée pour Field2, par exemple :

Faites attention lorsque vous accédez aux éléments VF à partir de JavaScript, car cela peut être un peu frustrant en fonction de la façon dont Visualforce génère le HTML - vous pouvez soit utiliser $Component, soit utiliser la syntaxe de l'arborescence des éléments générés.

Créez un champ de nombre (champ 1) puis créez un champ de formule (type : Nombre). Mettez dans la formule Test_Number__c + 30 , où Test_Number__c est le premier champ numérique. Cela devrait suffire à votre besoin comme indiqué. Veuillez noter que le champ de formule ne sera pas affiché dans la page d'édition, mais la valeur sera affichée dans la page de détail après avoir enregistré l'enregistrement d'opportunité.


Un champ obligatoire conditionnel peut-il être créé dans les formulaires SharePoint ?

J'ai une liste SharePoint avec quelques champs utilisés pour créer un répertoire d'imprimantes.

Au moment où j'ai le champ Oui/Non "Imprimante réseau" pour déterminer si je dois collecter des données supplémentaires comme l'adresse IP et le sous-réseau. Jusqu'à présent, je viens de marquer ce champ comme non obligatoire et de modifier le formulaire de saisie dans InfoPath afin qu'il les masque dès que quelqu'un choisit "Non" dans le choix de l'imprimante réseau, afin que l'utilisateur final sache qu'il n'a pas à remplir cette information dans.

J'aimerais que lorsque l'utilisateur choisit "Oui", il ne puisse pas ajouter l'élément à la liste tant que ces champs techniquement obligatoires ne sont pas remplis.


2 réponses 2

Je fais une chose similaire en fonction de l'entrée dans un menu déroulant, vous pouvez refactoriser cela pour vos besoins.

Ce qui précède retournera vrai si la condition est remplie, et faux sinon. Résultat dans un champ obligatoire sous condition.

Donc, si vous vouliez vous assurer qu'un champ n'était pas vide par exemple, vous pourriez faire quelque chose comme :

Cela renverra obligatoirement true s'il n'y a pas de texte dans le champ.

Vous pouvez également baser ces éléments sur diverses propriétés de style, voici un exemple de vérification si le champ a une bordure rouge :


Dimanche 24 juillet 2016

GIS5103 - Module 10 - Création d'outils personnalisés

Dans ce module, nous avons été chargés de créer un outil de découpage personnalisé. Transformer votre script Python en outil est un moyen simple de partager les fonctionnalités de votre script avec d'autres.

La première étape consistait à créer un script Python. On nous a fourni un modèle de script à modifier. Deuxièmement, une nouvelle boîte à outils a dû être créée. Après avoir ajouté un outil de script à la boîte à outils, nous configurons les propriétés de l'outil. Notre script Python modifié était le fichier de script et quatre paramètres ont été créés : emplacement du fichier d'entrée, entité de limite de découpage, caractéristiques d'entrée et emplacement du fichier de sortie. La configuration du type de données et des valeurs a été une étape importante. Les chemins de fichiers complets sont requis, mais les guillemets ne sont pas nécessaires.

Boîte de dialogue Outil MultiClip du module 10

Une fois les propriétés de l'outil définies, nous devions modifier notre script Python pour permettre aux utilisateurs de saisir les paramètres. L'utilisation des fonctions GetParameter() et GetParameterAsText() m'a causé quelques difficultés. J'avais besoin de comprendre si l'objet renvoyé était une chaîne ou non. Notre paramètre de caractéristiques d'entrée était une valeur multiple, ce qui signifie que plusieurs valeurs ou une liste pouvaient être fournies. Le script Python utilisait une boucle "for" pour parcourir chaque caractéristique d'entrée de la liste. Nous avons également dû remplacer les instructions "print" originales du script Python par la fonction AddMessage. L'utilisation des instructions AddMessage a permis aux messages d'apparaître dans la boîte de dialogue de progression de l'outil et la fenêtre de résultats.

Résultats de l'outil MultiClip du module 10
Pour chaque caractéristique d'entrée, le nom de la caractéristique est imprimé. Une fois l'analyse de découpage effectuée, le nom de l'entité découpée nouvellement créée est imprimé.

J'ai choisi de vérifier si l'outil fonctionnait également avec une autre fonction de limite. J'ai créé une carte affichant à la fois les entités découpées Durango et les entités découpées NuevoLeon.

Carte finale du module 10 -
Les entités d'entrée mex_rivers, mex_roads, mex_rails et mex_urban ont été coupées aux entités Durango et NuevoLeon.
Enfin, j'ai créé un organigramme du script utilisé dans l'outil.

Organigramme de script du module 10 MultiClip
Pour cette mission, j'ai dû utiliser les ressources d'aide d'ArcGIS pour mieux comprendre les fonctions du script et leurs arguments respectifs. Voir des exemples de code a été utile. J'ai également remarqué qu'il y avait parfois une différence dans la documentation entre pro.arcgis.com et desktop.arcgis.com

Cette mission m'a vraiment aidé à voir l'utilité des outils. Il est si facile de reproduire un outil parmi plusieurs fonctionnalités et différents paramètres.


1 réponse 1

Si vous vous souciez du temps, le temps devrait être dans votre base de données. Période. Vous voulez voir un cas où l'utilisation d'une séquence pourrait échouer (je ne sais pas si la même chose pourrait se produire avec les auto-incréments MySQL) ?

Lorsque vous demandez une valeur à partir d'une séquence à l'intérieur d'une transaction, vous ne tirez pas simplement la valeur suivante, la base de données vous réserve tout un bloc de valeurs. Ceci est fait pour réduire la surcharge liée au verrouillage correct de la séquence et à la gestion de plusieurs connexions simultanées. Regardons cette séquence d'événements :

  • Le client n°1 se connecte au serveur
  • Le client n°1 demande une valeur à une séquence
  • DB réserve 1-10 pour le client n°1, donne au client n°1 la valeur 1
  • Le client n°1 insère le 1 dans un tableau
  • Le client n°1 décide de faire quelque chose qui prendra du temps
  • Le client n°2 se connecte au serveur
  • Le client n°2 demande une valeur à une séquence
  • DB réserve 11-20 pour le client #2, donne au client #2 la valeur 11
  • Le client n°2 insère le 11 dans un tableau
  • Le client n°2 valide et se déconnecte
  • Le client n°1 demande la valeur suivante de la séquence
  • DB donne au client n°1 la valeur 2
  • Le client n°1 insère 2 dans une table
  • Le client n°1 s'engage et se déconnecte

Quel est l'état de la base de données maintenant ? Vous avez 1, 2 & 11 dans votre tableau mais la ligne avec le 2 est la plus récente. Le tri par cette valeur vous donne le mauvais résultat.


2 réponses 2

Ce que vous proposez de faire ne peut être fait avec MySQL proprement que sous trois (3) conditions

  • ÉTAT #1 : Utiliser le moteur de stockage MyISAM
  • ÉTAT #2 : Faire partie de la colonne auto_increment d'une clé primaire composée
  • ÉTAT #3 : chaque auto_increment pour un type donné doit exister dans sa propre ligne

Voici votre disposition de table originale

Sur la base des trois conditions que je viens de mentionner, voici la nouvelle disposition du tableau proposée :

Voici un exemple via des exemples de données et SQL :

ATTENTION : À l'heure actuelle, seul le moteur de stockage MyISAM prend en charge plusieurs valeurs auto_increment regroupées avec d'autres colonnes. Ce n'est pas possible avec InnoDB basé sur des colonnes auto_increment liées directement au gen_clust_index (alias index clusterisé) .


7 réponses 7

Lorsque vous grisez un contrôle, vous communiquez "quelque chose est actuellement désactivé, mais peut devenir disponible si vous faites autre chose sur la page".

Le seul inconvénient de cette approche est que les contrôles désactivés occuperont de l'espace sur la page, donc si ces contrôles désactivés sont rarement utilisés et/ou il y en a beaucoup, cela pourrait ajouter une complexité visuelle inutile pour très peu de valeur.

Lorsque vous cachez quelque chose et ne le révélez à la demande que lorsque cela est nécessaire (divulgation progressive), cela garantit que la page reste simple jusqu'à ce que les circonstances imposent l'affichage de contrôles supplémentaires.

Le seul inconvénient de cette approche est que la page devra s'adapter pour afficher les contrôles nouvellement révélés. Il est peu probable que l'utilisateur soit surpris par la divulgation progressive, car il s'agit d'un modèle d'interaction robuste qui existe depuis de nombreuses années.

Les deux approches sont valables et ont leurs avantages et leurs inconvénients. En fin de compte, votre décision sera basée sur la valeur des contrôles supplémentaires, la quantité de contrôles supplémentaires et la fréquence de leur utilisation.

Pourquoi avoir une zone de texte distincte pour chaque champ si l'utilisateur ne peut saisir une valeur qu'une seule fois ? Il suffit d'avoir une seule zone de texte pour contenir la valeur de l'option sélectionnée :

L'étiquette de la boîte peut changer en fonction de l'option sélectionnée. Vous pouvez soit masquer ce champ jusqu'à ce qu'ils aient sélectionné l'une des options, soit simplement lui donner un libellé générique afin qu'il puisse s'appliquer à n'importe laquelle des options.

Je peux voir les deux côtés de ces conceptions et je ne pense pas que l'un ou l'autre soit "faux", mais je recommanderais toujours de garder les choses simples pour l'utilisateur. Dans ce cas, cela signifierait que les cases soient visibles mais grisées.

Cela accomplit deux choses :

  1. L'utilisateur est conscient dès le début qu'il devra prouver du texte supplémentaire. Si la case était masquée, un pourcentage d'utilisateurs cocherait simplement la case et penserait qu'ils ont terminé, pour être ennuyés par l'erreur "Veuillez fournir des données" qui apparaîtrait.
  2. Il y a moins de soucis techniques. Votre mise en page ne changerait pas lorsque des éléments apparaissent / vous n'avez pas à vous soucier de l'effacement / de la conservation des données. Des choses simples mais elles ajoutent toutes aux conditions de test nécessaires pour votre produit.

Compte tenu de la nature des données que vous capturez, je contesterais l'utilisation de cases à cocher, par opposition aux sélections déroulantes. Les cases à cocher sont-elles nécessaires ? Ils sont toujours délicats, en particulier sur les conceptions pour appareils mobiles.

Dans l'entreprise où je travaille, l'équipe UX veut toujours "chaque entrée visible par l'utilisateur" d'une part parce que vous communiquez à l'utilisateur l'ensemble du processus, et d'autre part parce qu'un champ apparaissant est plus difficile à reconnaître, ce qui entraîne de nombreuses erreurs dans le remplissage du entrées avant de soumettre le formulaire.

C'est tout à fait toujours vrai, mais bien sûr, il existe des cas extrêmes, par exemple, si le formulaire est vraiment désordonné, alors nettoyer quelque chose et laisser le champ apparaître (d'une manière élégante pour être vu) pourrait être une meilleure façon.

Si vous les masquez d'abord et que vous les affichez une fois qu'un bouton radio a été choisi, vous devez indiquer que cela va se produire. Si vous ne le faites pas, les utilisateurs pourraient ne pas s'attendre à ce que cela se produise, et peuvent être confus ou même ennuyés par le fait qu'ils doivent faire "encore une autre" action pour remplir cette partie du formulaire.

Si vous ne pouvez pas indiquer clairement quelle sera la prochaine étape pour l'utilisateur, les montrer depuis le début mais les désactiver (et les griser par exemple) donnera probablement une meilleure vue de ce que l'utilisateur devra faire ensuite, offrant ainsi une meilleure expérience utilisateur.

Si nous parlons d'une page Web, sur des appareils mobiles avec des écrans plus petits, je peux imaginer que l'approche « masquer » est problématique.

Ma propre habitude lorsque je navigue sur mobile est de zoomer et d'ajuster la largeur du texte que je lis à la largeur de l'écran (en appuyant deux fois sur le texte). De cette façon, j'ai une taille de texte maximale sans perdre beaucoup d'informations sur l'endroit où je me trouve dans le document (au moins latéralement). Si vous optez pour l'approche « masquer » et que vos utilisateurs mobiles zooment sur le texte comme je le fais, ils ne verront initialement pas les champs de texte qui s'affichent lorsqu'ils font une sélection.

Je dirais donc "désactiver", ne pas "cacher".

Je préférerais les cacher et les montrer en survol. cela amènera à l'utilisateur l'idée qu'il doit sélectionner (cliquer) sur un champ pour y mettre un texte. l'utilisateur jouera d'abord avec le pointeur de haut en bas et il remarquera très facilement que la boîte de saisie restera affichée à chaque fois qu'il cliquera.

Je ne suis pas dans l'idée de le cacher complètement à moins que vous ne cliquiez sur . une action soudaine n'est pas une bonne pratique. et aussi je ne suis pas avec l'idée de les montrer et de le désactiver. vous mettez des éléments dans les pages pour ne pas les désactiver, cela donnera l'idée qu'il y a quelque chose qui ne va pas dans la page. et bien sûr, je ne suis pas d'accord pour combiner toutes les cases radio avec la zone de saisie, car cette solution ne rappellera pas qu'il existe une zone de saisie liée au bouton radio que je viens de sélectionner, et si l'utilisateur devait changer d'avis et sélectionnez un autre bouton radio !!

Ainsi, ma solution se situe entre toutes les autres solutions, cachant la zone de saisie et en même temps les montre ainsi que la décision entre les mains des utilisateurs. dépendent du moment de son pointeur.


Vous ne pouvez pas transmettre de paramètres aux liaisons de méthode créées dans votre page Visualforce à votre contrôleur, selon la rubrique d'aide ici, vous ne pouvez fournir que les méthodes 'action', 'get' et 'set'.

Afin de mettre en œuvre votre exigence, je vous recommanderais d'envisager de regarder les composants Visualforce, de sorte que vous puissiez avoir quelque chose comme

Ce composant utiliserait en interne le composant apex:outputText comme ci-dessus, mais son contrôleur aurait reçu la valeur 'test' en tant qu'attribut du composant. Sur le contrôleur, vous auriez un getFormattedValue pour afficher la version formatée.


Voir la vidéo: C# POO Démo 30 attribut auto increment (Octobre 2021).