IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinDev Discussion :

Excel Ole Automation Trier sur plusieurs colonnes [WD18]


Sujet :

WinDev

  1. #1
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut Excel Ole Automation Trier sur plusieurs colonnes
    Bonjour,

    je suis bloquée sur une syntaxe et bizarrement étrange je ne trouve rien sur le net!!!
    Voici mon problème :
    J'ouvre un classeur excel et je souhaite y effectuer un tri sur 3 colonnes.
    voici mon code qui ne fonctionne pas car ne combine pas le tri que je souhaite faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    MonXls est un objet OLE "Excel.Application" // créer l'objet dynamique
    MonXls >>visible = OLEVrai // rendre excel visible ou non
     
    // Ouverture du fichier XLS
    MonXls >>workbooks>>open("c/temp/monfichier.xls") // ouvre le classeur
    MonXls >>Sheets(1)>>Select()
    SI ErreurDétectée = Vrai ALORS
    	Erreur( ErreurInfo())	
    	RETOUR
    FIN
     
    nNbLigne_MonXls  =MonXls >>ActiveSheet>>UsedRange>>Rows>>Count
    MonXls >>Range("A1:I"+nNbLigne_MonXls)>>select()
     
    // on effectue le tri suivant : par G ; E; I
    MonXls >>Selection>>Sort(MonXls >>Range("G1"),1)
    MonXls >>Selection>>Sort(MonXls >>Range("E1"),1)
    MonXls >>Selection>>Sort(MonXls >>Range("I1"),1)
    Ce tri n'est pas correct car il ne les combine pas mais fait 1 apres l'autre.
    Comment dois je m'y prendre pour regrouper le tri?

    Merci par avance de vos lumieres
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 552
    Points : 1 193
    Points
    1 193
    Par défaut
    Bonjour,

    Comme vous l'avez constaté, le code que vous avez écrit tri successivement les colonnes en déclassant les autres à chaque fois.
    Voici la syntaxe VBA pour faire des tri puis des sous-tri, etc...

    Je vous laisse trouver la conversion en WLangage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("A2:A6"), _
            SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("C2:C6"), _
            SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("B2:B6"), _
            SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Feuil1").Sort
            .SetRange Range("A1:C6")
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
    End With
    Cordialement.

  3. #3
    Expert confirmé
    Homme Profil pro
    ?
    Inscrit en
    Juillet 2002
    Messages
    2 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ?

    Informations forums :
    Inscription : Juillet 2002
    Messages : 2 378
    Points : 4 494
    Points
    4 494
    Par défaut
    Bonjour

    Pour avoir la bonne syntaxe

    Sous Excel :
    - démarre l'enregistrement d'un macro
    - exécute ton tri sur tes 3 colonnes
    - arrête l'enregistrement de la macro

    Ensuite tu va dans VBA voir le code qui a été généré pour faire ça et tu traduis ça en WLanguage

    EDIT : ce que vient de faire Ry_Yo

  4. #4
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Un grand merci à Ry_Yo et hpascal pour vos elements de reponse.
    J'avoue que ça va beaucoup m'aider même si malheureusment je ne sais pas du tout comment traduire cela en WLanguage!!
    Je vais continuer mes recherches en esperant trouver un moyen de faire cela!!
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  5. #5
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Re,
    malheureusement je ne m'en sors pas la, rien ne passe !!!
    je ne vois pas du tout comment "traduire" cela en WLangage...et je trouve impressionnat qu'il n'existe aucune doc la dessus !!
    Si quelqu'un à des pistes, je prends !!
    Merci par avance
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  6. #6
    Membre actif
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Mai 2015
    Messages
    138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur COBOL

    Informations forums :
    Inscription : Mai 2015
    Messages : 138
    Points : 270
    Points
    270
    Par défaut question pour être sur
    Bonjour,

    Si je comprends bien ton problème c'est que suite a l'exécution de ton code tu te retrouve comme si tu avait fait un tri sur la 3ème colonne

    il trie par la première

    puis il trie par la deuxième (défaisant au passage le premier tri)

    et enfin par la troisième et défaisant le tri précédent

    C'est bien ça ?

  7. #7
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Oui c'est exactement cela rudolfrudolf.
    Je souhaiterai qu'il cumule mes tris a savoir Tri colonne 1 (qu'il garde), puis tri colonne 2 (qu'il garde) et enfin colonne 3 (qu'il garde)
    Mon code actuellement fait le tri sur 1, puis quand il fait le tri sur 2, il ne garde pas le tri effectué avant, puis quand il fait le tri sur 3, il ne tient pas comte des 2 autres tris
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  8. #8
    Membre actif
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Mai 2015
    Messages
    138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur COBOL

    Informations forums :
    Inscription : Mai 2015
    Messages : 138
    Points : 270
    Points
    270
    Par défaut est-ce envisagable
    Bien alors premier constat je ne connais absolument pas VBA - peux donc pas t'aider à traduire quoi que ce soit

    Par contre est il envisageable de concaténer tes 3 colonnes de tri en une seule afin de faire le tri sur celle la ?

  9. #9
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Merci rudolfrudolf, j'ai fais comme tu m'as suggéré!!
    Au début c'était pas mon choix de faire ainsi parce que je souhaiterais vraiment savoir l'équivalent du VBA en WLanguage pour ce cas de tri multiple (grrr!!) mais comme la il s'agit de tri croissant pour les 3, ça passe nickel de faire ainsi!!
    Encore merci pour le déblocage !!
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 552
    Points : 1 193
    Points
    1 193
    Par défaut
    Afin de comprendre VBA -> WLangage voici un exemple rapide

    en VBA : l'accès à un membre se fait par le .
    objet OLE : l'accès à un membre se fait par le >>

    Donc si on traduit cette syntaxe VBA en WLangage cela donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ----- VBA -----
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Clear
     
    ----- WL -----
    ActiveWorkbook>>Worksheets("Feuil1")>>Sort>>SortFields>>Clear
    Lorsque des paramètres sont attendus dans un membre, alors il suffit de nommer les paramètres. Comment savoir comment se nomme les paramètres ? un tour sur google avec les mots clefs : msdn + membre recherché...
    Ici une recherche de ce genre : "msdn excel SortFields.Add", nous permet de trouver tous les paramètres qu'il nous faut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ----- VBA -----
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("A2:A6"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
     
    ----- WL -----
    ActiveWorkbook>>Worksheets("Feuil1")>>Sort>>SortFields>>Add(Range("A2:A6"), xlSortOnValues, xlAscending, xlSortNormal)
    Enfin les instructions de type "With..... END" se traduit ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ----- VBA -----
    With ActiveWorkbook.Worksheets("Feuil1").Sort
            .SetRange Range("A1:C6")
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
    End With
     
    ----- WL -----
    Range est un objet OLE dynamique
     
    Range = MonXls>>Sheets(1)>>Range("A2:C8")
    ActiveWorkbook.Worksheets("Feuil1")>>Sort>>SetRange(Range)
    ActiveWorkbook.Worksheets("Feuil1")>>Sort>>Header(xlYes)
    ActiveWorkbook.Worksheets("Feuil1")>>Sort>>MatchCase(False)
    ActiveWorkbook.Worksheets("Feuil1")>>Sort>>Orientation(xlTopToBottom)
    ActiveWorkbook.Worksheets("Feuil1")>>Sort>>SortMethod(xlPinYin)
    ActiveWorkbook.Worksheets("Feuil1")>>Sort>>Apply()
    Et bien entendu google est toujours là pour nous aider à trouver la valeur des constantes Excel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CONSTANT
    	xlSortOnValues = 0
    	xlAscending = 1
    	xlDescending = 2
    	xlSortNormal = 0
    	xlSortTextAsNumbers = 1
    	xlTopToBottom = 1
    	xlPinYin =1
    	xlStroke = 2
    	xlGuess =0
    	xlNo =2
    	xlYes = 1
    	xlSortColumns =1
    	xlSortRows = 2
    FIN
    Voilà grosso-modo comment procédé pour interpréter le code généré par la macro... Bien entendu, faut tester, être sur que l'on se trouve sur le bon objet avant d'essayer d'accéder à un membre, etc...

  11. #11
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 947
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 947
    Points : 9 275
    Points
    9 275
    Par défaut
    hello,
    au cas où vous auriez des difficultés à utiliser les bouts de code de Ry__Yo (moi par exemple j'ai un :
    Erreur à la ligne 18 du traitement Clic sur Bouton20.
    Vous accédez au membre Automation Sort.
    Erreur 80020006, Nom inconnu
    sur l'instruction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonClasseur>>Worksheets("Feuil1")>>Sort>>SortFields>>Clear


    voici un bout de code qui fonctionne avec windev16 excel 2010 ( tri de trois colonnes dans la feuille "Personnes") :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    MonClasseur est un objet Automation dynamique
    MaFeuille est  un objet Automation dynamique
    // Instance de Excel existante ?
    SI ObjetActif("Excel.Application") <> Null ALORS
    	// Récupération de l'instance de Excel existante
    	MonClasseur = ObjetActif("Excel.Application")
    SINON
    	// Allocation de l'objet automation "MonClasseur"
    	MonClasseur = allouer un objet Automation "Excel.Application"
    FIN
    SI MonClasseur = Null ALORS
    	Erreur("Impossible de lancer Excel.")
    	RETOUR
    FIN
    // Excel est visible 
    MonClasseur>>Visible = True
    MonClasseur>>workbooks>>Open("F:\temp\monclasseur1.xls") // ouvre le classeur
    // MonClasseur>>Worksheets("Personnes")>>Sort>>SortFields>>Clear  plantage ici
    MaFeuille = MonClasseur>>Worksheets("Personnes")
    // expression .Sort(Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3)
    MaFeuille>>Range("A1:C23")>>Sort(MaFeuille>>Range("A1:A23"),xlAscending,"",MaFeuille>>Range("B1:B23"),xlAscending,...
    MaFeuille>>Range("C1:C23"),xlAscending,xlNo,1,OLEFaux,xlSortColumns,xlPinYin,xlSortTextAsNumbers)
    // 
    // placer code ici pour traitements suivants
    // 
    MonClasseur>>activeworkbook>>Close(OLEFaux)
    MonClasseur>>Quit()
    avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CONSTANT
    	xlSortOnValues = 0
    	xlAscending = 1
    	xlDescending = 2
    	xlSortNormal = 0
    	xlSortTextAsNumbers = 1
    	xlTopToBottom = 1
    	xlPinYin =1
    	xlStroke = 2
    	xlGuess =0
    	xlNo =2
    	xlYes = 1
    	xlSortColumns =1
    	xlSortRows = 2
    FIN
    dans le code du projet ou de la fenêtre

    P.S : je viens de m'apercevoir qu'il y aurait peut-être une erreur dans l'ordre des paramètres de Sort dans la doc microsoft en effet le sort est défini comme ceci dans la doc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     expression .Sort(Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3)
    quand j'utilise cet ordre le tri de la colonne 2 ne fonctionne pas chez moi donc j'ai plutôt fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     expression .Sort(Key1, Order1, Type, Key2,Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3)
    ce qui me paraissait plus logique car on ne coupe pas le Key2 et le Order 2 et là ça fonctionne (ce qu'il y a dans mon code le type est à "").
    Pourquoi cela alors n'aurait jamais été corrigé ? Peut-être parce qu'en VBA on utilise les paramètres nommés plutôt que l'ensemble des paramètres dans cette méthode.

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 552
    Points : 1 193
    Points
    1 193
    Par défaut
    C'est vrai que j'avais fait une traduction littérale sans vérifier.

    Le code ci-dessous fonctionne chez moi (office2010) avec cette déclaration d'objet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MonXls est un objet OLE "Excel.Application" // créer l'objet dynamique
    MonXls>>workbooks>>open(ComplèteRep(fRepExe()) + "Classeur1.xlsx") 
    MonXls>>Worksheets("Feuil1")>>Sort>>SortFields>>Clear
    Cordialement

  13. #13
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Merci Ry_Yo et jurassic pork pour vos explications plus detaillées.
    J'etais effectivement tombée sur la même erreur avec le "Sort" et n'étant pas experte en VBA, je ne voyais pas du tout comment me sortir de tout cela.
    Même si pour le coup j'ai fait différement le traitement et qui fonctionne à merveille, je vais tout de même tester une version avec ces éléments là. Je mettrai mon retour de test prochainement

    Bonne soirée à vous et merci encore !!
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  14. #14
    Expert éminent
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    3 947
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 3 947
    Points : 9 275
    Points
    9 275
    Par défaut
    hello,
    bon ben finalement j'ai trouvé pourquoi j'avais l'erreur "nom inconnu" sur l'instruction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonClasseur>>Worksheets("Feuil1")>>Sort>>SortFields>>Clear
    C'est parce que j'avais à la fois Excel 2003 et Excel 2010 installés sur ma machine et que le Excel.Application allait ouvrir l'Excel 2003. Comme l'objet "Sort" n'existe que depuis Excel 2007 , il n'était donc pas connu dans Excel 2003. J'ai donc désinstallé Excel 2003 et là ça fonctionne nettement mieux. Voici le code équivalent de ce que je faisait dans le code de mon message précédent en utilisant la méthode à Ry__Yo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // Declare variables to access the Excel workbook.
    objXLApp est un objet Automation dynamique
    MaFeuille  est un objet Automation dynamique
    MonTri  est un objet Automation dynamique
    MaPlage  est un objet Automation dynamique 
     
    // Instance de Excel existante ?
    SI ObjetActif("Excel.Application") <> Null ALORS
    	// Récupération de l'instance de Excel existante
    	objXLApp = ObjetActif("Excel.Application")
    SINON
    	// Allocation de l'objet automation Excel
    	objXLApp = allouer un objet Automation "Excel.Application"
    FIN
    SI objXLApp = Null ALORS
    	Erreur("Impossible de lancer Excel.")
    	RETOUR
    FIN
     
    objXLApp>>Visible = True
    objXLApp>>workbooks>>Open("F:\temp\monclasseur1.xls") // ouvre le classeur
    MaFeuille = objXLApp>>Worksheets("Personnes")
    MonTri = MaFeuille>>Sort
    MonTri>>SortFields>>Clear
    MonTri>>SortFields>>Add(MaFeuille>>Range("A1:A23"), xlSortOnValues, xlAscending, xlSortNormal)
    MonTri>>SortFields>>Add(MaFeuille>>Range("B1:B23"), xlSortOnValues, xlAscending, xlSortNormal)
    MonTri>>SortFields>>Add(MaFeuille>>Range("C1:C23"), xlSortOnValues, xlAscending, xlSortNormal)
    MaPlage = MaFeuille>>Range("A1:C23")
    MonTri>>SetRange(MaPlage)
    MonTri>>Header(xlNo)
    MonTri>>MatchCase(False)
    MonTri>>Orientation(xlTopToBottom)
    MonTri>>SortMethod(xlPinYin)
    MonTri>>Apply()
    Moralité : le code de mon message précédent fonctionne pour Excel 2003 et pour Excel 2010. Le code de ce message fonctionne pour Excel 2010.

    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [OpenOffice][Tableur] Comment trier numéros sur plusieurs colonnes par ordre croissant
    Par bordelaplage dans le forum OpenOffice & LibreOffice
    Réponses: 8
    Dernier message: 10/04/2015, 23h16
  2. Trier sur plusieurs colonnes
    Par tidusff10 dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 09/06/2012, 19h17
  3. Réponses: 6
    Dernier message: 11/03/2009, 12h43
  4. trier un stringgrid sur plusieurs colonnes
    Par renegade55 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 13/12/2005, 16h30
  5. Query sur plusieurs colonnes avec count(distinct...)
    Par Jeankiki dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/08/2004, 15h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo