ebook img

Sommaire Éditorial Article CRM Article Réseau PDF

79 Pages·2014·3.95 MB·French
by  
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview Sommaire Éditorial Article CRM Article Réseau

Édition de juin – juillet 2014 Numéro 52 Magazine en ligne gratuit Diffusion de copies conformes à l’original autorisée Réalisation : Alexandre Pottiez & Sébastien Lataix Rédaction : la rédaction de Developpez Contact : [email protected] Sommaire Article CRM OpenOffice-LibreOffice Page 2 CRM Page 16 2D/3D/Jeux Page 24 Reseau Page 35 Tester son code Apex Java Page 45 NoSQL Page 68 Comment tester son développement Apex avant une mise en production dans Salesforce? par Aurélien Laval Éditorial Page 16 Article Réseau Comme de coutume en cette pé- riode estivale, la rédaction se plie en quatre pour vous fournir le meilleur des publications de Deve- loppez.comauformatmagazineque La technologie Ethernet vous pouvez emmener sur la plage. Profitez-en bien et bonne vacances à tous! Ethernet est une technologie universelle qui dominait déjà les réseaux locaux bien avant le développement de Internet. La clé de la longévité de cette technologie, c’est sa simplicité. Souvent critiquée, elle a toujours été plus facile à utiliser et à mettre en œuvre que ses concurrentes. par Philippe Latu La rédaction Page 35 OpenOffice-LibreOffice Les derniers tutoriels et articles Utiliser oBasic dans le Tableur (Calc) Ce tutoriel ne sera qu’un élément de base pour la programmation, il ne contiendra pas toutes les com- mandes possibles, mais l’essentiel pour commencer à travailler avec le Tableur (Calc). Je ne vais pas chercher à faire au cours de ce tutoriel un comparatif entre oBasic et VBA. 1 Introduction 1.1 Qu’est-ce qu’une macro? Les macros pourront être écrites en oBasic, BeanShell,JavaScriptouPython.Toutefois,toutdé- Une macro est une suite d’instructions dans un pendra de votre environnement et de ce qui est ins- langage qui servira à les exécuter. Une macro est tallé par défaut sur le poste. Voici des captures sous souvent utilisée pour automatiser des tâches répéti- différents environnements. tives ou longues. — Sous Windows : — Sous Ubuntu : — Sous OpenSuse : Developpez Magazine est une publication de developpez.com page 2 Numéro 52 Juin–Juillet 2014 — Sous Debian : Comme vous pouvez le voir avec les captures précédentes, cela varie d’une distribution à une autre, mais dans ce tutoriel, je n’aborderai que la notion du oBasic, qui est commune à tous. 1.2 Où trouver l’éditeur de macros? L’éditeur de macro est accessible par la commande «Outils», «Macros», «Gérer les macros» et «LibreOffice Basic... » : La fenêtre suivante apparaît : Developpez Magazine est une publication de developpez.com page 3 Numéro 52 Juin–Juillet 2014 Dans la partie gauche de la fenêtre se trouvent pourront être utilisées). les emplacements de macros existantes : Danslapartiedroite,c’estlalistedesmacrosqui — «Mes macros» contiendra toutes les macros sont disponibles. qui seront rattachées au profil de la personne Pour ouvrir l’éditeur, deux cas possibles suivant qui est connectée; où vous vous trouvez : — « Macro LibreOffice » contiendra toutes les — soitvousvoulezmodifieroucompléterunema- macros qu’il sera possible d’utiliser avec la cro,danscecas,ilfaudracliquersur«Gérer» suite; et sélectionner la macro correspondante; — «Sansnom1»(oulenomd’unfichier)contien- — soit vous voulez créer une nouvelle macro et dra toutes les macros qu’il sera possible d’uti- dans ce cas cliquer sur «Nouveau». liser avec le fichier (si vous envoyez le fichier à quelqu’un,lesmacroscontenuesdanslefichier La fenêtre de l’éditeur est la suivante : L’exécution des macros est bloquée par défaut, ceci afin d’éviter des programmes indési- rables ou des virus. Vous trouverez ici une procédure pour activer correctement les macros. 2 L’éditeur oBasic L’éditeur oBasic se présente comme toute appli- d’outils, comme celle-ci, dont nous nous servirons cation : souvent : La fenêtre peut être décomposée en quatre parties : — la première partie contient toutes les com- mandes (menus, barres d’outils); — la deuxième contient les catalogues; — (1)permetdesélectionnerlemodulesouhaité; — la troisième contient le code; — (2) compile le code et permet d’identifier les — et la quatrième contient les témoins. erreurs; — (3) exécute la macro sélectionnée; 2.1 Menus et barres d’outils — (4)arrêteunemacroencours,ilestaussipos- Elle contient, entre autres, toutes les fonctions sible de faire Maj+Ctrl+S; d’édition standard aux suites, mais aussi des barres — (5) exécute une procédure et s’arrête; Developpez Magazine est une publication de developpez.com page 4 Numéro 52 Juin–Juillet 2014 — (6)exécutel’étapeets’arrêteàl’exécutionsui- nous permettra de nous déplacer facilement d’une vante; fonction à une autre pour modifier ou rajouter du — (7) retourne la précédente macro active; code dedans. Ilseraaussipossibledanscettezonedevisualiser — (8) insère un point d’arrêt; les points d’arrêt. Un point d’arrêt permet d’arrêter — (9) gère les points d’arrêt avec une boîte de le déroulement d’une macro sans la stopper au ni- dialogue; veau de l’opération qui se trouve juste avant. Par — (10) active ou désactive le témoin; exemple : — (11) met en évidence le texte entre deux pa- renthèses; — (12) ouvre le texte source oBasic dans la fe- nêtre; — (13) enregistre le code; — (14) permet d’importer une boîte de dialogue. 2.2 Les catalogues Un catalogue est l’emplacement où seront sto- ckées les différentes macros. Il en existe trois types : — «Mes macros et boîtes de dialogue» : il s’agit du catalogue contenant vos macros, celles-ci seront alors disponibles pour toutes les appli- cations; Il vous suffira de vous mettre sur la ligne 7, de cliquer sur la commande (1) et le point rouge (2) — «Macros et boîtes de dialogue...» : il s’agit apparaîtra sur la ligne. Si vous lancez votre macro, du catalogue dédié aux macros fournies avec toutes les commandes qui précèdent les points sont LibO et AOO ou les extensions; exécutées. — le catalogue du document chargé, mais la ma- cro ne sera alors disponible qu’avec le fichier. Les points d’arrêt sont très utiles quandvousdevezchercheruneerreur 2.3 Le code dans votre code. Cette partie contiendra tout le code. C’est dans cette zone que nous pourrons saisir de nouveaux 2.4 Le témoin codes ou modifier les codes existants. Lesdifférentscodesserontidentifiéspardesnoms Cette partie permet d’observer la valeur des va- defonctions(nousenreparleronsparlasuite),cequi riables au cours de l’exécution du code. 3 Quelques principes Comme dit précédemment, une macro est un bout de code écrit, dans notre cas, en oBasic. Elle exécutera une suite d’opérations dans le fichier Ta- bleur. Voici, au travers de quelques exemples, ce qu’il est possible de faire... Exemple 1, nous affichons un message : 1 Sub Exemple_1 Exemple 2, nous affichons un message que 2 nous aurons saisi : 3 Dim Txt as String 4 1 Sub Exemple_2 5 Txt = "Hello World !" 2 6 3 Dim Txt as String 7 MsgBox Txt 4 8 5 Txt = InputBox ("Titre") 9 End Sub 6 7 MsgBox Txt 8 Nous obtiendrons donc : 9 End Sub Developpez Magazine est une publication de developpez.com page 5 Numéro 52 Juin–Juillet 2014 La fenêtre suivante apparaît : Dans les deux exemples précédents, nous avons utilisé les balises Sub, mais nous aurions pu utiliser les ba- lises Function. Les deux codes fonctionnent égale- ment avec les autres applications de Nous saisissons le texte souhaité : la suite bureautique. Nous venons de voir comment se compose une ma- cro : — une balise d’ouverture et une de fermeture; Nous obtenons donc : — ladéclarationdesvariables,cetteétapeestim- portante,carelleestsouventsourced’erreurs; — lecontenudelamacroquidécritlesdifférentes opérations à réaliser. 4 Onglets 4.1 Lister les onglets présents dans le clas- permet d’indiquer que nous allons travailler seur surledocument.Nousaurionspumettremon- Document = CurrentComponent, cette pre- Voici le code qui nous permettra de lister tous mière notation nous indique que c’est le docu- les onglets contenus dans le classeur : ment actif qui est utilisé. La seconde notation 1 Sub ListerOnglet() permet d’intervenir sur un autre document; 2 Dim monDocument As Object — lesFeuilles = monDocument.Sheets : 3 Dim lesFeuilles as Object 4 Dim uneFeuille As Object permet d’indiquer que nous allons travailler 5 Dim nbF as Integer sur les différentes feuilles de l’onglet; 6 — lesFeuilles.Count : 7 monDocument = ThisComponent 8 lesFeuilles = monDocument.Sheets donnelenombredefeuillesquecontientleclas- 9 nbF = lesFeuilles.Count seur; 10 11 For i = 0 to nbF-1 — For i = 0 to nbF-1 ... Next : 12 uneFeuille = lesFeuilles(i) va nous permettre de balayer toutes les 13 MsgBox uneFeuille.Name feuilles : 14 Next 15 Attention, le premier onglet cor- 16 End Sub respondàlavaleur0,etilnefau- Explications : dra pas oublier de retirer 1 au nombre total, sinon vous obtien- — il est recommandé de définir toutes les va- drez une belle erreur. riables,celapermetd’enconnaîtreletypepour la suite : — uneFeuille = lesFeuilles(i) : Trèsutile,quandlecodeestlong. permet de sélectionner une feuille; Vouspourrezainsivoussouvenir — MsgBox uneFeuille.Name : du type que vous aviez associé à nous donne le nom de la feuille. la variable. Créez un nouveau classeur, insérez-y différents on- glets, copiez le code dans une nouvelle macro et exécutez-la. Sivousneladéfinissezpas,lava- leur par défaut est Object. 4.2 Quelques commandes 4.2.a Sélectionner une feuille par son nom — monDocument = ThisComponent : Developpez Magazine est une publication de developpez.com page 6 Numéro 52 Juin–Juillet 2014 1 Sub SelectionnerFeuille() 7 lesFeuilles = monDocument.Sheets 2 Dim monDocument As Object 8 uneFeuille = lesFeuilles.getByName(" 3 Dim lesFeuilles as Object Feuille1") 4 Dim uneFeuille As Object 9 uneFeuille.Name = "Feuille renommée" 5 10 6 monDocument = ThisComponent 11 ... 7 lesFeuilles = monDocument.Sheets 12 8 uneFeuille = lesFeuilles.getByName(" 13 End Sub Feuille1") 9 4.5 Insérer/supprimer une feuille 10 ... 11 12 End Sub 1 Sub Inserer_Supprimer() 2 Dim monDocument As Object 4.3 Détecter la feuille active 3 Dim lesFeuilles as Object 4 Dim uneFeuille As Object 1 Sub FeuilleActive() 5 Dim indexFeuille As Integer 2 6 3 ... 7 monDocument = ThisComponent 4 8 lesFeuilles = monDocument.Sheets 5 Msgbox ThisComponent. 9 CurrentController.ActiveSheet. 10 ’Pour insérer une feuille après la Name feuille sélectionnée 6 11 uneFeuille = lesFeuilles.getByName(" 7 ... Feuille1") 8 12 indexFeuille = uneFeuille. 9 End Sub RangeAddress.Sheet 13 lesFeuilles.insertNewByName("Feuille 4.4 Renommer une feuille insérée", indexFeuille+1) 14 1 Sub RenommerFeuille() 15 ’Pour supprimer une feuille 2 Dim monDocument As Object 16 lesFeuilles.removeByName("Feuille1") 3 Dim lesFeuilles as Object 17 4 Dim uneFeuille As Object 18 5 19 End Sub 6 monDocument = ThisComponent 5 Cellules Une des particularités du Tableur de LibreOffice 16 (ou OpenOffice) est que vous ne pourrez pas sélec- 17 ’Par sa position (colonne, ligne) 18 maCellule = maFeuille. tionner une colonne ou une ligne, vous serez obligé getCellRangeByPosition(1,10) de sélectionner une zone. 19 20 End Sub 5.1 Sélectionner une cellule 5.1.b Une zone 5.1.a Une cellule Il existe trois façons de sélectionner une cellule : 1 Sub SelectionnerZone() 2 Dim monDocument As Object 1 Sub SelectionnerCellule() 3 Dim lesFeuilles as Object 2 Dim monDocument As Object 4 Dim maFeuille As Object 3 Dim lesFeuilles as Object 5 Dim maCellule As Object 4 Dim maFeuille As Object 6 5 Dim maCellule As Object 7 monDocument = ThisComponent 6 8 lesFeuilles = monDocument.Sheets 7 monDocument = ThisComponent 9 maFeuille = lesFeuilles.getByName(" 8 lesFeuilles = monDocument.Sheets Feuille1") 9 maFeuille = lesFeuilles.getByName(" 10 Feuille1") 11 ’Par son adresse 10 12 maCellule = maFeuille. 11 ’Par son adresse getCellRangeByName("A1:A10") 12 maCellule = maFeuille. 13 getCellRangeByName("A10") 14 ’Par son nom (si vous avez donné un 13 nom à une zone) 14 ’Par son nom (si vous avez donné un 15 maCellule = maFeuille. nom à une cellule) getCellRangeByName("Zone_nommée" 15 maCellule = maFeuille. ) getCellRangeByName("Cellule_nomm 16 ée") 17 ’Par sa position (colonne, ligne) Developpez Magazine est une publication de developpez.com page 7 Numéro 52 Juin–Juillet 2014 18 maCellule = maFeuille. 5 Dim maCellule As Object getCellRangeByPosition(1,1,1,10) 6 19 7 monDocument = ThisComponent 20 End Sub 8 lesFeuilles = monDocument.Sheets 9 maFeuille = lesFeuilles.getByName(" 5.1.c La cellule active Feuille1") 10 maCellule = maFeuille. 1 Sub CelluleActive() getCellRangeByName("A1") 2 Dim maCellule As Integer 11 maCellule.String = "Texte que vous 3 voulez mettre dans la cellule" 4 maCellule = ThisComponent. 12 CurrentSelection 13 End Sub 5 MsgBox maCellule.CellAddress.Column 5.2.c Une formule 6 MsgBox maCellule.CellAddress.Row 7 MsgBox maCellule.CellAddress.Sheet 8 1 Sub EcrireFormule() 9 End Sub 2 Dim monDocument As Object 3 Dim lesFeuilles as Object 5.1.d La dernière cellule d’une ligne 4 Dim maFeuille As Object 5 Dim maCellule As Object 1 Sub DerniereCellule() 6 2 Dim monDocument As Object 7 monDocument = ThisComponent 3 Dim lesFeuilles as Object 8 lesFeuilles = monDocument.Sheets 4 Dim maFeuille As Object 9 maFeuille = lesFeuilles.getByName(" 5 Dim maCellule As Object Feuille1") 6 Dim maPosition As Object 10 maCellule = maFeuille. 7 getCellRangeByName("A1") 8 monDocument = ThisComponent 11 9 lesFeuilles = monDocument.Sheets 12 ’Pour une formule en anglais 10 maFeuille = lesFeuilles.getByName(" 13 maCellule.Formula = "=SUM(A1:A100") Feuille1") 14 11 15 ’Pour une formule avec la langue du 12 maPosition = maFeuille.createCursor poste en français 13 maPosition.gotoEndOfUsedArea(False) 16 maCellule.FormulaLocal = "=SOMME(A1: 14 MsgBox maPosition.RangeAddress. A100") EndRow+1 17 15 ’le +1 permet de se positionner sur 18 End Sub la dernière ligne vide 16 5.3 Lire une cellule 17 End Sub Tout comme pour écrire dans une cellule, la lec- 5.2 Écrire dans une cellule ture est soumise aux mêmes conditions. Pour les exemples qui vont suivre, nous allons Il y a plusieurs façons d’écrire dans une cellule saisir les données suivantes dans un classeur : suivant ce que vous voulez y mettre. — A1 contient la valeur 1; 5.2.a Une valeur numérique — A2 contient le texte «Test»; — A3 contient la formule « =SOMME(B1:B6) » 1 Sub EcrireValeur() (dans mon cas la somme fera 21). 2 Dim monDocument As Object 3 Dim lesFeuilles as Object 4 Dim maFeuille As Object Il n’y aura aucun message d’erreur si 5 Dim maCellule As Object vous vous trompez sur la commande. 6 Car la valeur que vous obtenez est 7 monDocument = ThisComponent «0». 8 lesFeuilles = monDocument.Sheets 9 maFeuille = lesFeuilles.getByName(" Feuille1") 10 maCellule = maFeuille. 5.3.a Une valeur getCellRangeByName("A1") 11 maCellule.Value = 1 12 ’Vous pouvez y mettre aussi un 1 Sub EcrireFormule() calcul 2 Dim monDocument As Object 13 3 Dim lesFeuilles as Object 14 End Sub 4 Dim maFeuille As Object 5 Dim maCellule As Object 5.2.b Du texte 6 7 monDocument = ThisComponent 1 Sub EcrireTexte() 8 lesFeuilles = monDocument.Sheets 2 Dim monDocument As Object 9 maFeuille = lesFeuilles.getByName(" 3 Dim lesFeuilles as Object Feuille1") 4 Dim maFeuille As Object 10 Developpez Magazine est une publication de developpez.com page 8 Numéro 52 Juin–Juillet 2014 11 maCellule = maFeuille. 15 getCellRangeByName("A1") 16 maCellule = maFeuille. 12 Msgbox maCellule.Value getCellRangeByName("A3") 13 17 Msgbox maCellule.Formula 14 maCellule = maFeuille. 18 getCellRangeByName("A2") 19 End Sub 15 Msgbox maCellule.Value 16 Ce qui nous donne pour les différentes Msgbox : 17 maCellule = maFeuille. getCellRangeByName("A3") — 1; 18 Msgbox maCellule.Value 19 — Test; 20 End Sub — SUM(B1 :B6). Ce qui nous donne pour les différentes Msgbox : — 1; Si vous aviez mis FormulaLocal, le résultat aurait été =SOMME(B1:B6). — 0; — 21. 5.4 Effacer le contenu d’une cellule 5.3.b Du texte La suppression agit de la même façon que la lec- 1 Sub LireTexte() ture, elle tient compte du type. Nous allons conser- 2 Dim monDocument As Object ver les mêmes données qu’avant : 3 Dim lesFeuilles as Object 4 Dim maFeuille As Object — A1 contient la valeur 1; 5 Dim maCellule As Object 6 — A2 contient le texte «Test»; 7 monDocument = ThisComponent 8 lesFeuilles = monDocument.Sheets — A3 contient la formule «=SOMME(B1:B6)». 9 maFeuille = lesFeuilles.getByName(" Feuille1") 10 maCellule = maFeuille. getCellRangeByName("A1") 5.4.a Une valeur 11 Msgbox maCellule.String 12 13 maCellule = maFeuille. 1 Sub EffacerValeur() getCellRangeByName("A2") 2 Dim monDocument As Object 14 Msgbox maCellule.String 3 Dim lesFeuilles as Object 15 4 Dim maFeuille As Object 16 maCellule = maFeuille. 5 Dim maCellule As Object getCellRangeByName("A3") 6 Dim aEffacer As Long 17 Msgbox maCellule.String 7 18 8 monDocument = ThisComponent 19 End Sub 9 lesFeuilles = monDocument.Sheets Ce qui nous donne pour les différentes Msgbox : 10 maFeuille = lesFeuilles.getByName(" Feuille1") — 1; 11 — Test; 12 aEffacer = com.sun.star.sheet. CellFlags.VALUE — 21. 13 14 maCellule = maFeuille. getCellRangeByName("A1") 5.3.c Une formule 15 maCellule.clearContents(aEffacer) 16 1 Sub LireFormule() 17 maCellule = maFeuille. 2 Dim monDocument As Object getCellRangeByName("A2") 3 Dim lesFeuilles as Object 18 maCellule.clearContents(aEffacer) 4 Dim maFeuille As Object 19 5 Dim maCellule As Object 20 maCellule = maFeuille. 6 getCellRangeByName("A3") 7 monDocument = ThisComponent 21 maCellule.clearContents(aEffacer) 8 lesFeuilles = monDocument.Sheets 22 9 maFeuille = lesFeuilles.getByName(" 23 End Sub Feuille1") 10 maCellule = maFeuille. Ce qui nous donne pour les différentes cellules : getCellRangeByName("A1") 11 Msgbox maCellule.Formula — A1 ne contient plus aucune donnée; 12 13 maCellule = maFeuille. — A2 contient «Test»; getCellRangeByName("A2") 14 Msgbox maCellule.Formula — A3 contient «=SUM(B1:B6)». Developpez Magazine est une publication de developpez.com page 9 Numéro 52 Juin–Juillet 2014 5.4.b Du texte 15 16 maCellule = maFeuille. 1 Sub EffacerTexte() getCellRangeByName("A2") 2 Dim monDocument As Object 17 maCellule.clearContents(aEffacer) 3 Dim lesFeuilles as Object 18 4 Dim maFeuille As Object 19 maCellule = maFeuille. 5 Dim maCellule As Object getCellRangeByName("A3") 6 20 maCellule.clearContents(aEffacer) 7 monDocument = ThisComponent 21 8 lesFeuilles = monDocument.Sheets 22 End Sub 9 maFeuille = lesFeuilles.getByName(" Ce qui nous donne pour les différentes cellules : Feuille1") 10 — A1 contient «1»; 11 aEffacer = com.sun.star.sheet. — A2 contient «Test»; CellFlags.STRING 12 — A3 ne contient plus aucune donnée; 13 maCellule = maFeuille. getCellRangeByName("A1") 14 maCellule.clearContents(aEffacer) 5.4.d Tout supprimer 15 16 maCellule = maFeuille. Ilexisteunefaçondetouteffacerd’unseulcoup: getCellRangeByName("A2") 17 maCellule.clearContents(aEffacer) 1 Sub EffacerTout() 18 2 Dim monDocument As Object 19 maCellule = maFeuille. 3 Dim lesFeuilles as Object getCellRangeByName("A3") 4 Dim maFeuille As Object 20 maCellule.clearContents(aEffacer) 5 Dim maCellule As Object 21 6 22 End Sub 7 monDocument = ThisComponent 8 lesFeuilles = monDocument.Sheets Ce qui nous donne pour les différentes cellules : 9 maFeuille = lesFeuilles.getByName(" — A1 contient «1»; Feuille1") 10 — A2 ne contient plus aucune donnée; 11 aEffacer = com.sun.star.sheet. — A3 contient «=SUM(B1:B6)». CellFlags.VALUE +_ 12 com.sun.star.sheet. CellFlags.STRING +_ 5.4.c Une formule 13 com.sun.star.sheet. CellFlags.FORMULA 1 Sub EffacerFormule() 14 2 Dim monDocument As Object 15 maCellule = maFeuille. 3 Dim lesFeuilles as Object getCellRangeByName("A1") 4 Dim maFeuille As Object 16 maCellule.clearContents(aEffacer) 5 Dim maCellule As Object 17 6 18 maCellule = maFeuille. 7 monDocument = ThisComponent getCellRangeByName("A2") 8 lesFeuilles = monDocument.Sheets 19 maCellule.clearContents(aEffacer) 9 maFeuille = lesFeuilles.getByName(" 20 Feuille1") 21 maCellule = maFeuille. 10 getCellRangeByName("A3") 11 aEffacer = com.sun.star.sheet. 22 maCellule.clearContents(aEffacer) CellFlags.FORMULA 23 12 24 End Sub 13 maCellule = maFeuille. Toutes les cellules A1, A2 et A3 sont maintenant getCellRangeByName("A1") 14 maCellule.clearContents(aEffacer) vides. 6 Conclusion Nous venons de voir quelques-unes des fonctions qui vous permettront de commencer la programma- tion avec oBasic. La liste des fonctions est longue, vous pouvez toutes les découvrir dans cet ouvrage : Programmation OpenOffice.org et LibreOffice. À vous maintenant de vous lancer dans la programmation et de développer vos propres applications. Retrouvez l’article de Vincent Viale en ligne : lien 6 Developpez Magazine est une publication de developpez.com page 10 Numéro 52 Juin–Juillet 2014

Description:
12. // Compare des valeurs. 13. System.assertEquals(5.0,. myWebServiceCalculatorCallout. divide(numerator, denominator)). ;. 14. 15. Test.stopTest();.
See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.