tag:blogger.com,1999:blog-84328125010725030782024-03-05T17:58:32.875+01:00Salesforce für EntwicklerAuszüge aus Projekten, Beispielcode, Tipps und Tricks aus dem Bereich Salesforce.Unknownnoreply@blogger.comBlogger87125tag:blogger.com,1999:blog-8432812501072503078.post-60244562697679626322018-01-16T09:56:00.000+01:002018-01-16T09:56:04.852+01:00Community Builder funktioniert nicht<br />
Nachdem ich eine in einer Sandbox konfigurierte und getestete <b>Lightning</b> <b>Community</b> per Changeset auf die Produktion übertrage und bereitgestellt hatte, stellte ich fest, dass sich die Community nicht konfigurieren lässt. Das Deployment lief fehlerfrei durch. Alle Komponenten der Lightning Community sind verfügbar. Jedoch erscheint die Fehlermeldung<br />
<br />
<div style="text-align: center;">
<span style="font-family: -webkit-standard; text-size-adjust: auto;"><span style="color: red;"><b>Cannot read property 'def' of undefined</b></span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoMcXWdVjDApcKMQ9lLVty-aqDlHI9kK2NMruGZ3tEx55pkT7jRir5sdJrbggdyNUYKvLDypAO0wbAMmudbQ72Gef67Gt0ColKrgWmYTbnfEOlhD3_ntW0UXiUUJoKhHddQASeXc1B0u47/s1600/Community+Builder+2018-01-16+08-34-47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="620" data-original-width="1117" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoMcXWdVjDApcKMQ9lLVty-aqDlHI9kK2NMruGZ3tEx55pkT7jRir5sdJrbggdyNUYKvLDypAO0wbAMmudbQ72Gef67Gt0ColKrgWmYTbnfEOlhD3_ntW0UXiUUJoKhHddQASeXc1B0u47/s640/Community+Builder+2018-01-16+08-34-47.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: left;">
sobald ich auf den "Builder" - Link klicke.</div>
<div style="text-align: left;">
<br /></div>
<br />
<b>Folgendes Workaround löst das Problem:</b><br />
<br />
<span style="font-family: -webkit-standard; text-size-adjust: auto;">1. Go to "All Communities" and click on "Workspaces" beside the problematic community.</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">2. Go to "Administration | Pages" and click on "Go to Site.com Studio".</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">3. Once site.com studio has finished loading, click on the "Site Actions" icon (small cog in top right of screen), and select "Export This Site".</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">4. When prompted, specify a local location to save the site export, and wait for the file download to complete.</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">5. After the download is complete, click on "Site Actions" again, and select "Overwrite This Site".</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">6. When prompted, select the file downloaded from #4, and click on 'Overwrite'.</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">7. After the upload is complete, go back to the "All Communities" view and click on "Builder" to open the community in community builder.</span><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><br style="font-family: -webkit-standard; text-size-adjust: auto;" /><span style="font-family: -webkit-standard; text-size-adjust: auto;">8. Click on "Publish".</span><br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-5316113448168025362017-06-26T13:09:00.000+02:002017-06-26T13:09:05.548+02:00Bad value for restricted picklist fieldDer Einsatz von "Restricted Picklists" bereitet spätestens im Deployment Kopfschmerzen.<br />
Basiert das Deployment auf Basis eines Drittanbietertools, dann sind die Kopfschmerzen noch intensiver.<br />
<br />
In meinem Fall habe ich versucht, ein neues Picklist-Feld mit Copado zu deployen.<br />
Während der Bereitstellung bekomme ich die folgende Fehlermeldung:<br />
<br />
<span style="color: red;">System.DmlException: Insert failed. First exception on row 0; first error: INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST, bad value for restricted picklist field: Z012: [CountryGroup__c]</span><br />
<br />
Das neue Picklist-Feld übernimmt alle Werte aus einem Global Value Set.<br />
Das bedeutet, die Option "Restrict to the values defined in the value set" ist automatisch aktiv und lässt sich nicht deaktivieren.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGX0GKt8XGztFIfhdux2DQwJ9HsqAONX1YS54bbU53X9Sf-99XHqhqgSEZoZIjW7Y7n4kGAxu3cBZiMctuxnANAltG9Q7eXpF9RQqINLiCtp9IxgcJBDo9EXqRLH8QJU72axyBhd534HOq/s1600/restrictedPicklist.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="766" data-original-width="926" height="528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGX0GKt8XGztFIfhdux2DQwJ9HsqAONX1YS54bbU53X9Sf-99XHqhqgSEZoZIjW7Y7n4kGAxu3cBZiMctuxnANAltG9Q7eXpF9RQqINLiCtp9IxgcJBDo9EXqRLH8QJU72axyBhd534HOq/s640/restrictedPicklist.png" width="640" /></a></div>
<br />
Eine APEX-Testklasse beschreibt ebenfalls die neue Pickliste.<br />
<br />
Mit dem folgenden Workaround konnte ich das Deployment-Problem lösen:<br />
1) Global Value Set samt Pickliste per Changeset in die Zielorg übertragen und bereitstellen<br />
<br />
<ul>
<li>ggf. Profilberechtigungen anpassen, falls irgendwelche Testklassen mit bestimmten Profilen arbeiten.</li>
</ul>
<br />
2) Anschließend alle Picklist-Werte für alle Record Types freischalten.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv3t5S0XC7YWujLsu21TWcBQWufVY-nissDjTESRMfbYzVVNmPxxBp7Hhx3lj7FUu6pgISr_QmPsaSals6B6KTf2B1FL6KpeR_5urKDIBlR-6bN8saJRRmbYgwJo4KAeqCInzhHkqqoic9/s1600/picklistRecType.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="582" data-original-width="411" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv3t5S0XC7YWujLsu21TWcBQWufVY-nissDjTESRMfbYzVVNmPxxBp7Hhx3lj7FUu6pgISr_QmPsaSals6B6KTf2B1FL6KpeR_5urKDIBlR-6bN8saJRRmbYgwJo4KAeqCInzhHkqqoic9/s400/picklistRecType.png" width="281" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
3) Das ganze Paket inkl. Picklisten, RecordTypes, Apex etc. deployen.</div>
<br />
<br />
<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-5967128704106889672017-06-19T11:15:00.001+02:002017-06-19T11:15:49.472+02:00Territory Management & Reports<br />
In einer Org mit aktiviertem Feature "Territory Management" habe ich einen neuen Bericht gebaut, der alle Assets kategorisiert nach Account darstellen soll. Im Bericht sind alle Accounts mit Assets aufgelistet, auf die ich Zugriff über mein Territory habe.<br />
<br />
<b>Problem</b>:<br />
einige Assets erscheinen mehrfach im Bericht (s. Screenshot)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3vRFTyN7pdOmw_9U8SGAbM-wSBzPqS8ZHeyKuw1UFZfUYIedN_pRQ0jA9a3PpCrreH6RO-3DwCvohEpri08gbyGdIr77vhdEcNZn3w6Qx9aOjNR_PDLlb8SfFP5p_N6IWJCdvwxtZBIHv/s1600/assets.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="436" data-original-width="847" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3vRFTyN7pdOmw_9U8SGAbM-wSBzPqS8ZHeyKuw1UFZfUYIedN_pRQ0jA9a3PpCrreH6RO-3DwCvohEpri08gbyGdIr77vhdEcNZn3w6Qx9aOjNR_PDLlb8SfFP5p_N6IWJCdvwxtZBIHv/s640/assets.png" width="640" /></a></div>
<br /><b>Lösung</b>:<br />
der entsprechende Account ist einem Territory mehrfach zugewiesen: höchstwahrscheinlich durch die manuelle Zuweisung zuerst, und anschließend durch die Auslösung der Assignment Rules.<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-85626190313402963602017-04-10T12:00:00.000+02:002017-04-10T12:00:19.706+02:00Reset Security TokenAufgrund bestimmter Einstellungen bleibt der Link "Reset Security Token" verborgen. Falls ein Entwickler einen neuen Token braucht, kann er die Reset Token Seite über den folgenden Link direkt aufrufen, ohne Einstellungen zu "verbiegen".<br />
<br />
<span id="AnswersHome:ForumLayout:j_id162"><strong class="feedText" id="ext-gen78">https://<b id="ext-gen97">[<span style="color: blue;">SalesforceInstanz</span>]</b>/_ui/system/security/ResetApiTokenEdit?retURL=%2Fui%2Fsetup%2FSetup%3Fsetupid%3DPersonalInfo&setupid=ResetApiToken</strong></span><br />
<strong class="feedText"><br /></strong>
<strong class="feedText"><br /></strong>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-15606139297169132362017-04-03T15:56:00.002+02:002017-04-03T15:56:53.261+02:00Zeitgesteuerter Flow blockiert Custom Leadkonvertierung Die programmierte Konvertierung eines Leads bricht mit der Fehlermeldung "Unable to convert lead that is in use by workflow" ab.<br />
<br />
Der Grund ist ein Prozess, der automatisiert und zeitgesteuert ausgeführt wird.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq5MhkY2W3yLVEafYOh7kJyRREIK0Cluu2yS3We-zsWWEGhwu4kVGVnm7X3cPHKabOAFpHv_yc3kX4ZhQSucaAhJ7YoLoZ-aXf3_8b8TYxsxQ38yD-8FGAVkjk-F90Ev0dEOHHzwqtPT3N/s1600/2017-04-03+15_31_25-Process+Builder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq5MhkY2W3yLVEafYOh7kJyRREIK0Cluu2yS3We-zsWWEGhwu4kVGVnm7X3cPHKabOAFpHv_yc3kX4ZhQSucaAhJ7YoLoZ-aXf3_8b8TYxsxQ38yD-8FGAVkjk-F90Ev0dEOHHzwqtPT3N/s400/2017-04-03+15_31_25-Process+Builder.png" width="400" /></a></div>
<br />
Dieser Prozess ruft zu einem späteren Zeitpunkt einen Flow auf. Während der Speicherung eines Leads wird dabei automatisch ein Flow Interview erstellt.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDGqxx6N_Tb35OmixapVem3TRuEZkEUYlTEBNnLqtyFU-ycnn-g4sDok7K9E9nBXoQLO5SHKady6mi8mmUyG8iycDUue_gzvjPD7wJmW4kTPCOO1FEbv5ze_CHFP2hvuqY8V1DWvmTAU83/s1600/2017-04-03+15_32_58-Flows+%257E+Salesforce+-+Enterprise+Edition.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDGqxx6N_Tb35OmixapVem3TRuEZkEUYlTEBNnLqtyFU-ycnn-g4sDok7K9E9nBXoQLO5SHKady6mi8mmUyG8iycDUue_gzvjPD7wJmW4kTPCOO1FEbv5ze_CHFP2hvuqY8V1DWvmTAU83/s400/2017-04-03+15_32_58-Flows+%257E+Salesforce+-+Enterprise+Edition.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Dieser Datensatz vom Typ "FlowInterview" blockiert die Leadkonvertierung.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Lösung:</b></div>
<div class="separator" style="clear: both; text-align: left;">
Unmittelbar vor der Leadkonvertierung eine Checkbox auf dem Lead auf TRUE setzen.</div>
<div class="separator" style="clear: both; text-align: left;">
Da dieselbe Checkbox in den Process Builder Kriterien eingebunden ist und der Prozess nur auf den FALSE Wert reagiert, löscht das System automatisch das entsprechende Flow Interview.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUmGokMhobvXsqOLagExs5rO1NmEU-sgdG819IjbCT5F-xY4T8G632MyvUp39bLO4ZDlXtO34L8rBiALrGAXacT_3UrGC1efy_JBPgOYYNFH0oDgkCoCVi-uokjAo-MYRtSyawfGjbnche/s1600/2017-04-03+15_50_07-Process+Builder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUmGokMhobvXsqOLagExs5rO1NmEU-sgdG819IjbCT5F-xY4T8G632MyvUp39bLO4ZDlXtO34L8rBiALrGAXacT_3UrGC1efy_JBPgOYYNFH0oDgkCoCVi-uokjAo-MYRtSyawfGjbnche/s400/2017-04-03+15_50_07-Process+Builder.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-32281835787457194752016-12-19T12:00:00.000+01:002016-12-19T12:00:12.946+01:00Crazy SOQL<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gODFfin4YuOnR4oaGqmEiijxdGjDQLKZK0Nx409G1eXoUpotPmKq5IiovvgH1O4RBiN8gHLb5PSK_q2DKDcYCgIj-YQ04P4pwMHbWosh5jwlBCmYNVJg16GwQgS5zcWlm3TZ_j2-Ousx/s1600/crazy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gODFfin4YuOnR4oaGqmEiijxdGjDQLKZK0Nx409G1eXoUpotPmKq5IiovvgH1O4RBiN8gHLb5PSK_q2DKDcYCgIj-YQ04P4pwMHbWosh5jwlBCmYNVJg16GwQgS5zcWlm3TZ_j2-Ousx/s320/crazy.jpg" width="320" /></a></div>
<br />
<br />
Genauso habe ich heute geschaut, als ich den folgenden Code ausgeführt und das Ergebnis ausgewertet habe:<br />
<br />
<pre class="brush:java;">CustomObj__c obj = [select LookupField__c from CustomObj__c where <b>LookupField__c != NULL</b> AND Id = 'hereisavalidid'];
system.debug(' <b>LookupField__c darf nicht NULL sein</b>');
if(obj.LookupField__c == null){
system.debug('<b>Also doch NULL</b>');
}
</pre>
<br />
<br />
Und was sehen meine müde Augen im Log...<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfItGL7So2sofgT-Jn_ZRj2Ql-ZPIjVGr0dmRMYQ_9naDqtZXb7fS0vuoBAp4tMSNmQjYDBakcb3KzNDNLHy5xgkj9PswyXalDCKAkP1oLbltrsDFkO9nvUB0Dfx-GeNVmqqwuwyz2L1V-/s1600/console.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfItGL7So2sofgT-Jn_ZRj2Ql-ZPIjVGr0dmRMYQ_9naDqtZXb7fS0vuoBAp4tMSNmQjYDBakcb3KzNDNLHy5xgkj9PswyXalDCKAkP1oLbltrsDFkO9nvUB0Dfx-GeNVmqqwuwyz2L1V-/s1600/console.jpg" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>LookupField__c </b>ist ein Lookup- und Pflichtfeld, somit darf eigentlich per Definition nicht NULL sein.<br />
Offensichtlich gibt es (alte) Daten im System mit dem <b>LookupField__c = NULL</b><br />
<b><br /></b>
Habe erwartet, dass die SOQL Abfrage die NULL-Daten filtert.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-85489304942887402232016-12-16T16:14:00.002+01:002016-12-16T16:14:36.686+01:00Neues Jahr - Neue VorsätzeNach einer laaaaangen Pause, habe ich mir vorgenommen, wieder etwas aktiver zu sein.<br />
<br />
Salesforce ist wie ein bodenloser Topf. Es ist immer wieder erstaunlich, welche krassen Lösungen dieser Topf zubereitet, wenn der Koch die richtige Portionierung einzelner Zutaten kennt.<br />
Und davon gibt es viele: Lightning, Web Services, Vlocity, Continuous Integration...<br />
<br />
Das Thema "Zertifizierungen", das ich auch in den Angriff nächstes Jahr nehmen und darüber berichten werde, ist ebenfalls interessant und anspruchsvoll.<br />
<br />
Vorsätze gibt es viele. Ich warte aber nicht bis 2017, sondern fange gleich nächste Woche an.<br />
Bis Montag ;-)<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-16181747557101228302016-04-14T12:05:00.000+02:002016-12-16T15:40:21.983+01:00Emails mit APEX | SINGLE_EMAIL_LIMIT_EXCEEDED Email-Versand mit Visualforce und Apex kann schon manchmal Kopfschmerzen bereiten....<br />
<br />
Entweder ist die Email zu groß, oder zu viele Attachments oder der HeapSize "beschwert sich" oder, wenn letztendlich alles läuft, man wird von den Salesforce Limits zurück zum Ausgangspunkt katapultiert.<br />
<br />
Das kann doch nicht so schwer sein!<br />
Ist es auch nicht, wenn man das schon einmal gemacht hat ;-)<br />
<br />
Habe eine Visualforce Maske zum Versenden von HTML Emails programmiert.<br />
Diese werden als SingleEmailMessage gesendet:<br />
<div style="text-align: center;">
<span style="color: blue;">Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });</span></div>
<br />
Sobald die Anzahl der pro Tag gesendeten Emails den Salesforce Limit "knackt", wird dem User die entsprechende Meldung eingeblendet.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/eom30WUAWdk/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/eom30WUAWdk?feature=player_embedded" width="320"></iframe></div>
<br />
Die auf die Org bezogene Limitierung lässt sich mit<span style="color: blue;"> LIMITS.getLimitEmailInvocations()</span> berechnen.<br />
<br />
Hier ein Auszug aus den "Execution Governors and Limits"<br />
<a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm">https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm</a><br />
<br />
<i><strong>A Dev Edition org has a single email limit of 10 messages.</strong> (assuming 1 recipient per email)</i><br />
<i><strong>A non Dev org has a single email limit of 1000 messages.</strong> (assuming 1 recipient per email)</i><br />
<i><br /></i>
<i>Using the API or Apex, you can send single emails to a maximum of
1,000 external email addresses per day based on Greenwich Mean Time
(GMT).</i><br />
<br />
<br />
/*+++++++++++++++++++++++++++++++++++++++++<br />
sendApexMail<br />
*/<br />
<pre class="brush:java;"> public pagereference sendApexMail(){
Pagereference pr;
transient Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
// Set the Subject and Body
mail.setSubject(mailSubject);
mail.setHtmlBody(mailHtmlBody);
String sToMailBCC = '';
String sReplyToEmail = UserInfo.getUserEmail(); //userEmail;
// To: or Cc:
set<String> setToMail = new set<String>();
set<String> setCcMail = new set<String>();
if(mailTo.contains(',')) setToMail.addAll(mailTo.split(','));
else setToMail.add(mailTo);
if(selectedAdditionalRecipient.trim() != ''){
if(selectedAdditionalRecipient.contains(',')) setCcMail.addAll(selectedAdditionalRecipient.split(','));
else setCcMail.add(selectedAdditionalRecipient);
}
mail.setToAddresses(new list<String>(setToMail));
// CC:
if(!setCcMail.isEmpty()) mail.setCcAddresses(new list<String>(setCcMail));
// BCC:
if(sToMailBCC != '') mail.setBccAddresses(new String[] {sToMailBCC});
// Reply To:
mail.setReplyTo(sReplyToEmail);
// Attachments (only active)
Decimal totalSize = 0;
set<Id> setIdAtt = new set<Id>();
for(ParentAttachment pa:lstParentAttachments){
if(pa.isActive){
totalSize += pa.att.BodyLength;
setIdAtt.add(pa.att.id);
}
}
// Append Attachments
transient List<Messaging.Emailfileattachment> lstFileAttachments = new List<Messaging.Emailfileattachment>();
transient list<Attachment> lstAttachmentsToClone;
if(!setIdAtt.isEmpty()){
lstAttachmentsToClone = new list<Attachment>([select Name, Body, ParentId from Attachment where id in:setIdAtt OR Description=:objQuote.Id]);
for(Attachment attach :lstAttachmentsToClone){
Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
efa.setFileName(attach.Name);
efa.setBody(attach.Body);
lstFileAttachments.add(efa);
}
}
if(!lstFileAttachments.isEmpty())
mail.setFileAttachments(lstFileAttachments);
// Send Email
try{
//Messaging.reserveSingleEmailCapacity(2);
List<Messaging.SendEmailResult> emailSendResults;
transient Decimal decHeap = Limits.getHeapSize();
transient Decimal decHeapMax = 5570000; // <-- tested successfully with this size. max Heap Size is 6MB, but createActivity() uses heap size, too
transient Double dblAllowedSize = 2.5;
if(decHeapMax - decHeap < 0){
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, LABEL.QFX_message_EmailNotSent));
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, LABEL.QFX_message_AllowedSize + ' ' + dblAllowedSize.format() + ' MB'));
}else{
try{
String emailErrorReport;
emailSendResults = Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
for( Messaging.SendEmailResult currentResult : emailSendResults ) {
if( currentResult.getErrors() != null ) {
for( Messaging.SendEmailError currentError : currentResult.getErrors()){
emailErrorReport = emailErrorReport + '(' + currentError.getStatusCode() + ') ' + currentError.getMessage() + '\r' ;
}
}
}
System.debug(emailSendResults);
if(emailErrorReport == null){
createActivity(contactSendTo, objQuote.Id, mailSubject, mailHtmlBody, lstAttachmentsToClone);
// View Quote
pr = backToQuote();
}else{
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, emailErrorReport));
}
}catch(System.HandledException he){
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'HandledException: ' + he.getMessage()));
}catch(Exception e){
String sMsg = LABEL.QFX_message_SendEmailFailedLimit;
sMsg = sMsg.replace('%LIMIT%' , String.valueof(LIMITS.getLimitEmailInvocations()));
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, sMsg));
}
}
}catch (Exception e) { ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage())); }
return pr;
}
</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-90197882795636897692016-02-24T14:53:00.003+01:002016-02-24T14:55:26.540+01:00Dynamic SOQL - Auswertung der Felder vom Related ObjectEin Custom Object ist mit dem Standard Account Object über ein Lookup-Feld verknüpft.<br />
Abhängig vom Country ISO Code auf dem Account wird die Sprache auf dem Projekt automatisch gesetzt.<br />
Da die oben beschriebene Konfiguration ein Teil eines Managed Packages ist, und die Country ISO Codes nicht in jeder Org konfiguriert sind, muss die Logik mit Einsatz von "<a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dynamic_soql.htm" target="_blank">dynamic soql</a>" implementiert werden.<br />
<br />
Bei der Auswertung der ISO Codes erscheint die <span style="color: red;"><b>Fehlermeldung</b></span>:<br />
<div style="text-align: center;">
<span style="color: red;"><i>Invalid field Account__r.BillingCountryCode for sf42_prfxpe__Project__c</i></span></div>
<br />
<span style="color: #38761d;"><b>Lösung</b></span>: zuerst Account über die Relation definieren, dann das entsprechende Feld auswerten<br />
<div style="text-align: center;">
<i><span style="color: #38761d;">sObject objRelAccount = objProject.getSObject('Account__r');</span></i></div>
<br />
<pre class="brush:java;">String sSoql = 'SELECT Id, Name, Account__c, Account__r. BillingCountryCode FROM Project__c';
for (Project__c p : Database.query(sSoql)){
sObject objRelAccount = objProject.getSObject('Account__r');
if(objRelAccount != null){
String sIsoCode = (String)objRelAccount.get('BillingCountryCode');
}
}
</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-17529370988503291282016-02-12T12:00:00.000+01:002016-02-26T17:32:57.677+01:00Sortieren einer APEX Liste mit Wrapper Objekten einfach gemachtEine Visualforce Seite zeigt alle Feiertage in diesem Jahr.<br />
Jeder Feiertag entspricht einem Salesforce Objekt.<br />
Die Liste wird dynamisch aufgebaut und ist somit unsortiert.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9xynXKR2px_JY2VxWyww42WRvpsEFI9ReHwclXlSHF3TXOWVOOWBCyMTcMXxEji1p4T9J-WoNRrJ8ULewD29_qZT2YdUSM9QkVpYrmUild4mw1q6JnQrJZ3tFigx06vZ-TCp1JDN29cIX/s1600/holidaysDialog.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9xynXKR2px_JY2VxWyww42WRvpsEFI9ReHwclXlSHF3TXOWVOOWBCyMTcMXxEji1p4T9J-WoNRrJ8ULewD29_qZT2YdUSM9QkVpYrmUild4mw1q6JnQrJZ3tFigx06vZ-TCp1JDN29cIX/s1600/holidaysDialog.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Der entsprechende Code sieht ungefähr so aus:<br />
<br />
<pre class="brush:java;">public list<HOLIDAYS> getHoliday(){
list<HOLIDAYS> lstHolidays = new list<HOLIDAYS>();
...
lstHolidays.add(new HOLIDAYS(obj, true));
...
return lstHolidays;
}
</pre>
<pre class="brush:java;">/******************************
*** HOLIDAYS
******************************
public class HOLIDAYS{
public Holiday__c objHoliday{get; set;}
public String holidayName{get; set;}
public Id holidayId{get; set;}
public String holidayDate{get; set;}
public Decimal duration{get; set;}
public Boolean isChecked{get; set;}
public HOLIDAYS(Holiday__c h, Boolean isChecked){
this.objHoliday = h;
this.holidayName = h.Name;
this.holidayId = h.id;
this.holidayDate = h.Date__c.format();
this.duration = h.Duration__c;
this.isChecked = isChecked;
}
}
</pre>
<br />
Mit dem Einsatz der sort() Methode und einer kleinen Anpassung der Wrapper Klasse wird die Liste nach Datum sortiert ausgegeben:<br />
<br />
<pre class="brush:java;">public list<HOLIDAYS> getHoliday(){
list<HOLIDAYS> lstHolidays = new list<HOLIDAYS>();
...
lstHolidays.add(new HOLIDAYS(obj, true));
...
lstHolidays.sort();
return lstHolidays;
}</pre>
<br />
Einsatz von Comparable Interface<br />
<br />
<pre class="brush:java;">public class HOLIDAYS implements Comparable{
public Holiday__c objHoliday{get; set;}
public String holidayName{get; set;}
public Id holidayId{get; set;}
public String holidayDate{get; set;}
public Decimal duration{get; set;}
public Boolean isChecked{get; set;}
public HOLIDAYS(Holiday__c h, Boolean isChecked){
this.objHoliday = h;
this.holidayName = h.Name;
this.holidayId = h.id;
this.holidayDate = h.Date__c.format();
this.duration = h.Duration__c;
this.isChecked = isChecked;
}
// Compare holidays based on the date
public Integer compareTo(Object compareTo) {
HOLIDAYS compareToHoliday = (HOLIDAYS)compareTo;
// The return value of 0 indicates that both elements are equal.
Integer returnValue = 0;
if (objHoliday.Date__c > compareToHoliday.objHoliday.Date__c) {
// Set return value to a positive value.
returnValue = 1;
else if (objHoliday.Date__c < compareToHoliday.objHoliday.Date__c) {
// Set return value to a negative value.
returnValue = -1;
}
return returnValue;
}
}
</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-43913341378719214252016-01-25T17:14:00.000+01:002016-01-25T17:14:50.607+01:00PDF - DateinameSobald eine mit Visulaforce generierte PDF-Datei über die Standard Schaltfläche gespeichert werden soll, stellt man fest, dass der Dateiname automatisch vom System vergeben wurde, wie zum Beispiel "document.pdf".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEeeJRlrYW0jhTDJoORDsMGTTmDe_7GjTNLl6tIYjJ3kTblztfppgZcI19FA9hH4PhNrL2f3_fBB7JWVcmpyy2FFZf-_el6kr3rwp3UUGZ06Bq2IgyEatLEvMdKNXF9ehiyEMF7w9vhDUk/s1600/quote.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="283" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEeeJRlrYW0jhTDJoORDsMGTTmDe_7GjTNLl6tIYjJ3kTblztfppgZcI19FA9hH4PhNrL2f3_fBB7JWVcmpyy2FFZf-_el6kr3rwp3UUGZ06Bq2IgyEatLEvMdKNXF9ehiyEMF7w9vhDUk/s640/quote.png" width="640" /></a></div>
<br />
Leider bietet Salesforce keine entsprechende apex:page Eigenschaft für den Dateinamen.<br />
<br />
Der Name lässt sich allerdings über eine Header-Eigenschaft definieren.<br />
Diese wird wiederum von Controller gesetzt. Ich habe eine neue Funktion geschrieben, die von der Visualforce Seite aufgerufen wird. Genauso gut kann die Eigenschaft vom Constructor gesetzt werden.<br />
<br />
<span style="color: blue;"><apex:page controller="anyController" showheader="false" applyBodyTag="false" applyHtmlTag="false" renderAs="PDF" action="</span><b style="background-color: white;"><span style="color: #0b5394;">{!setFileName}</span></b><span style="color: blue;">"></span><br />
<br />
<br />
<pre class="brush:java;">public void setFileName(){
String pdfName = 'Angebot_' + Date.now().format();
Apexpages.currentPage().getHeaders().put( 'content-disposition', 'inline; filename=' + pdfName );
}
</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-67422687151363457622015-12-04T11:30:00.000+01:002015-12-04T11:30:00.586+01:00Salesforce Community getContentAsPDF()Ursachenforschung kann in manchen Fällen nicht nur zeitintensiv, sondern auch nervenraubend sein. Insbesondere dann, wenn sich die zu testende Funktion innerhalb eines komplexen Konstruktes befindet. Mit der folgenden Beschreibung kann ich vielleicht dem einen oder anderen Entwickler eine Menge Streß ersparen ;-)<br />
<br />
<b>Funktion:</b><br />
Generierung einer PDF Datei per Button (aus einer VisualForce Seite heraus). Anschließend wird die PDF Datei als Attachment an einen Datensatz angehängt.<br />
<br />
<b>Ausgangslage:</b><br />
Die oben beschriebene Funktion ist ein Teil eines in der Org installierten Managed Packages. Sie wird von einem Salesforce Community User ausgelöst. Weitere Informationen dazu gibt es in meinem letzten Beitrag <a href="http://develex.blogspot.de/2015/12/salesforce-community-url-settings.html" target="_blank">Salesforce Community URL Settings</a>. <br />
<br />
<b>Problem:</b><br />
Kein Attachment nach der Funktionsausführung im System verfügbar.<br />
Die folgende Fehlerseite erscheint:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7vV1AJ8YwhNJMnJ2rYYPFfbUQk-fGcE32kqXENxeVw1wjf47h6mJ537tBOxSxRALVrHHKOBOrhp1BFwvlA39A6cRPzkKjRXXYwWJREhrp_J9C4rhEAZfYOSoMWqdkn_pcLKGupryGYXR/s1600/errorPDF.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="390" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7vV1AJ8YwhNJMnJ2rYYPFfbUQk-fGcE32kqXENxeVw1wjf47h6mJ537tBOxSxRALVrHHKOBOrhp1BFwvlA39A6cRPzkKjRXXYwWJREhrp_J9C4rhEAZfYOSoMWqdkn_pcLKGupryGYXR/s640/errorPDF.jpg" width="640" /></a></div>
Ursache identifizieren:<br />
Als erstes fange ich an, die Logs auszuwerten. Da die im managed Package implementierten Debug-Ausgaben in der Test-Org nicht erscheinen, muss ich<br />
<ol>
<li>dem Hersteller des managed Packages den Zugriff auf die Test-Org erlauben<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6gTwhSe15-TJW11LuCi-qFImYQ3l3MT0sD33bHgS0VA9oUr5nh-jYesAA9B__IXssfjIPUbPYfel6M9frd0TRiIQX80HxRmVgoWV_FYfxJpnSnHUpZ5hnOAor6uA0hBGD0V-fF5DVjUJl/s1600/grantLoginAccess.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6gTwhSe15-TJW11LuCi-qFImYQ3l3MT0sD33bHgS0VA9oUr5nh-jYesAA9B__IXssfjIPUbPYfel6M9frd0TRiIQX80HxRmVgoWV_FYfxJpnSnHUpZ5hnOAor6uA0hBGD0V-fF5DVjUJl/s400/grantLoginAccess.jpg" width="400" /></a> </li>
<li>um mich anschließend über den Hersteller-Zugriff (Hersteller-org des Managed Packages > Tab "Subscriber Organizations") in der Test-Org einzuloggen. </li>
</ol>
Erst jetzt kann ich Debug-Ausgaben im Log-Bereich für den Community User konfigurieren.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6EYLgWzVKFqs7mK0FyLRUKHwu1Q3ijPNWKfgfJ8GsTdET83kFgI4fgHlAtLvTgHdDPm0vqsptBufsDjIPYAzPkdyPt5pQzt5V6a3BWnIgUiXOtVRRcVedCj46syjwzU6gESbvGVXKwmME/s1600/debugCOmmunity.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="48" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6EYLgWzVKFqs7mK0FyLRUKHwu1Q3ijPNWKfgfJ8GsTdET83kFgI4fgHlAtLvTgHdDPm0vqsptBufsDjIPYAzPkdyPt5pQzt5V6a3BWnIgUiXOtVRRcVedCj46syjwzU6gESbvGVXKwmME/s640/debugCOmmunity.jpg" width="640" /></a></div>
<br />
<br />
<br />
Mit dem Community User einen Test gemacht...<br />
Im "Hersteller-Log" erscheinen deutlich mehr Informationen. Doch in Bezug auf die Attachment-Generierung geht das System sehr sparsam mit Informationen um.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBK4vXMYlIy2HsbnUwrm8gFAqBE_vx2BQOnhtHsbi8W6oQGIH6_1plZSurF1sDZwdqf1HYhsCA4nS3o4YUpjeYkACJ2ySvAKz6NgsduA0K9TQfImde3vZTYqz0GftqFXTSFGLfahXrGAkn/s1600/getContentAsPDF.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="59" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBK4vXMYlIy2HsbnUwrm8gFAqBE_vx2BQOnhtHsbi8W6oQGIH6_1plZSurF1sDZwdqf1HYhsCA4nS3o4YUpjeYkACJ2ySvAKz6NgsduA0K9TQfImde3vZTYqz0GftqFXTSFGLfahXrGAkn/s640/getContentAsPDF.jpg" width="640" /></a></div>
Nur "SYSTEM_MODE_EXIT | true"???<br />
Mehr bekomme ich leider nicht. <br />
<br />
Nach vielen weiteren Tests <i>unter anderem mit dem aktivierten und deaktivierten Critical Update "PageReference getContent() and getContentAsPDF() Methods Treated as Callouts" </i>bin ich zum Ergebnis gekommen, dass die Referenzierung der PDF Seite innerhalb des Managed Packages für einen Community User nicht korrekt funktioniert.<br />
<br />
<b>Ursache:</b><br />
<span style="color: blue;">pdfPage</span>.getContentAsPDF() funktioniert nicht, weil das System die <span style="color: blue;">pdfPage <span style="color: black;">nicht findet (obwohl die PDF Generierung innerhalb des Managed Packages läuft).</span></span><br />
<br />
<b>Lösung: </b><br />
Für Community Benutzer wird der absolute Pfad bei der Initialisierung der PDF Seite verwendet.<br />
Die beiden folgenden Funktionen sind etwas ausführlicher Beschrieben im <a href="http://develex.blogspot.de/2015/12/salesforce-community-url-settings.html" target="_blank">letzten Beitrag</a>:<br />
<ul>
<li>isCommunityUser()</li>
<li>communitySiteURL()</li>
</ul>
<br />
<pre class="brush:java;">PageReference pdfPage;
// absolute URL only for Community User
if(isCommunityUser()){
String serverUrl = communitySiteURL();
// remove last slash
if(serverUrl != ''){
if(serverUrl.right(1) == '/'){
serverUrl = serverUrl.substringBeforeLast('/');
}
}
pdfPage = new PageReference(serverUrl + '/apex/sf42_quotefx__QFX_pdf');
}else{
pdfPage = Page.QFX_pdf;
}</pre>
<br />
Zusatzinfo: Initialisierung der PDF Seite außerhalb des Managed Packages funktioniert reibungslos:<br />
<pre class="brush:java;">pdfPage = Page.sf42_praefix__QFX_pdf;</pre>
<pre class="brush:java;"> </pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-63845761850554403972015-12-03T12:00:00.000+01:002015-12-03T12:45:17.458+01:00Salesforce Community URL SettingsIch habe mich in den letzten Tagen etwas ausführlicher mit Salesforce Communities in Kombination mit der API beschäftigt. Ein Problem dabei war, den richtigen Endpoint zu berechnen, wie im letzten Beitrag beschrieben <a href="http://develex.blogspot.de/2015/11/api-im-salesforce-partner-portal.html" target="_blank">API im Salesforce Partner Portal.</a><br />
<br />
Um die Weichen im Code für Community Benutzer einzubauen, muss während der Laufzeit berechnet werden, in welchem Context sich der aktuell eingeloggte Benutzer befindet. Dabei muss man sich zwangsweise mit den Fragen folgender Art beschäftigen:<br />
<ol>
<li>ist der eingeloggte Benuter ein Community Benutzer?</li>
<li>ob und welche Community ist gerade aktiv?</li>
<li>wie sieht die definierte Community URL aus?</li>
</ol>
<b>Antwort auf die Frage 1: </b><br />
<pre class="brush:java;">private Boolean isCommunityUser(){
Boolean bIsCommunityUser = false;
String sUserType = UserInfo.getUserType();
sUserType = sUserType.toUpperCase();
if(sUserType == 'STANDARD') bIsCommunityUser = false;
if(sUserType == 'PARTNER') bIsCommunityUser = true;
if(sUserType == 'POWERPARTNER') bIsCommunityUser = true;
if(sUserType == 'CSPLITEPORTAL') bIsCommunityUser = true;
if(sUserType == 'CUSTOMERSUCCESS') bIsCommunityUser = true;
if(sUserType == 'POWERCUSTOMERSUCCESS') bIsCommunityUser = true;
if(sUserType == 'CSNONLY') bIsCommunityUser = false;
return bIsCommunityUser;
}
</pre>
<br />
<br />
<b>Antworten auf die Fragen 2 und 3: </b> <br />
<pre class="brush:java;">String baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
if(isCommunityUser()){
// <b>Antwort auf die Frage 2</b>
String communityId = Network.getNetworkId();
if(communityId!=null){
// <b>Antwort auf die Frage 3</b>
ConnectApi.Community cm = connectapi.Communities.getCommunity(communityId);
baseUrl = cm.siteUrl;
}
}
</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-19219381391189138392015-11-27T11:30:00.000+01:002015-11-27T11:30:00.948+01:00API im Salesforce Partner Portal Eine von uns entwickelte Salesforce Applikation kommt im Partner Portal zum Einsatz.<br />
Diese beinhaltet unter anderem eine Visualforce Seite mit einer integrierten Flex-Applikation. <br />
Folgendes Abbild stellt das gesamte Konstrukt vereinfacht dar.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlSUVPJbqMZLIwAvYlDcLmxQbUBiAKGaPYdHcw9kad3eHHdxIf6wohP9GMMWIcXfa8WTVzNVt2UWcKY-hF-mZdv1KEPd6bufGVSRqKctjA7DnIr4kZUsGA2kuseqHjkqpLQ4smqGTVsj4c/s1600/Partner_ApiCalls.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="324" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlSUVPJbqMZLIwAvYlDcLmxQbUBiAKGaPYdHcw9kad3eHHdxIf6wohP9GMMWIcXfa8WTVzNVt2UWcKY-hF-mZdv1KEPd6bufGVSRqKctjA7DnIr4kZUsGA2kuseqHjkqpLQ4smqGTVsj4c/s640/Partner_ApiCalls.jpg" width="640" /></a></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrEpDjLEy-eQ7BewqrNNPmBYieLycTkQWJIKMXCLqh_hgL3zoIqvpqtKQ235NyslKVGBGtW-A-ODEBhhyphenhyphenZe3PTHtr1FqpSZeTf-HUzpmIdyL9fNR6N99D1stafW4UclL74rB8WAaCVv2RH/s1600/Partner_ApiCalls.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Die Flex-Applikation bedient sich der Daten aus der aktuellen Salesforce-Instanz.</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<b>Fehler</b></div>
<div style="text-align: left;">
im Partner-Portal kann trotz der aktivierten API-Einstellung keine Datenabfrage erfolgen</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b>Ursache</b></div>
<div style="text-align: left;">
der Controller der Visualforce-Seite übergibt den "falschen" Endpoint an die Flex App.</div>
<div style="text-align: left;">
</div>
<br />
<div style="text-align: left;">
Im Partner-Portal Context sieht die URL (in einer Sandbox) so aus:</div>
<div style="text-align: left;">
<span style="color: blue;">https://full-myorg-fullsb.cs80.force.com</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
und wird wie folgt berechnet:</div>
<div style="text-align: left;">
<br /></div>
<pre class="brush:java;">System.URL.getSalesforceBaseUrl().getHost();</pre>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b>Lösung</b></div>
<div style="text-align: left;">
Statt Partner-Portal-URL muss die Salesforce-Instanz-URL eingesetzt werden: </div>
<div style="text-align: left;">
<span style="color: blue;">https://cs80.force.com</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Diese lässt sich wie folgt vom Controller berechnen</div>
<div style="text-align: left;">
<br /></div>
<pre class="brush:java;">ApexPages.currentPage().getHeaders().get('X-Salesforce-Forwarded-To');</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-81226647683887245932015-11-20T13:48:00.000+01:002015-11-20T13:50:43.036+01:00CANNOT_EXECUTE_FLOW_TRIGGEREin Kunde teilte mit, dass er keine Anpassungen mehr in die Produktion übertragen kann, weil eine bestimmte Testklasse nicht durchläuft.<br />
<br />
Die Testklasse wirft die folgende Fehlermeldung aus:<br />
<br />
<span style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; display: inline !important; float: none; font-family: "proximanovaregular"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">System.DmlException:
Insert failed. First exception on row 0; first error:
CANNOT_EXECUTE_FLOW_TRIGGER, The record couldn’t be saved because it
failed to trigger a flow. </span><br />
<span style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; display: inline !important; float: none; font-family: "proximanovaregular"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;"><br /></span>
<span style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; display: inline !important; float: none; font-family: "proximanovaregular"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;"></span>Offensichtlich hat es was mit FLOWS zu tun...<br />
Im Setup unter Create > Workflows & Approvals > "<a href="https://developer.salesforce.com/page/Lightning_Process_Builder" target="_blank">Process Builder</a>" nachgeschaut, und festgestellt, dass mehrere Prozesse konfiguriert wurden.<br />
<br />
Welcher ist der Richtige?<br />
Um den richtigen Prozess zu finden, schaue ich mir die entsprechende Log-Ausgabe der Testklasse genauer an, und finde die folgenden Zeilen:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVvgxeHAaHZCXNmuwe9ju5Iw0kks8hcT3piSbKRqBpH6M9F5PcBv2ctNemVVurYYTIijAzBMQCRTjgNxCRHdHmX7L-SvONTnZExkbx65xs24O8FxgauxLT07YtCqzomc3agrOCG3NK2X8v/s1600/Console.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="38" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVvgxeHAaHZCXNmuwe9ju5Iw0kks8hcT3piSbKRqBpH6M9F5PcBv2ctNemVVurYYTIijAzBMQCRTjgNxCRHdHmX7L-SvONTnZExkbx65xs24O8FxgauxLT07YtCqzomc3agrOCG3NK2X8v/s640/Console.jpg" width="640" /></a></div>
<br />
<br />
Der Prozess heisst "New Contact" und er läuft nicht durch, weil "UserRole" nicht existiert.<br />
<br />
Habe den Prozess "New Contact" unter die Lupe genommen. Dieser enthält eine simple Inhaber-Zuweisung:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE3FinoOCMefgbeC6X7wFB-5g-TU7AZF9n2YuMXAcxHnhyXhA7CwW_r9iYNJZvI_Wjyyh5DlvuLzhpTIvwjqOHyF00RDj-wocOt0Tq9Kg0JUKWzGjS5N0sxJcTx0fqQRH-HN97gwLUMFHy/s1600/Process.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="104" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE3FinoOCMefgbeC6X7wFB-5g-TU7AZF9n2YuMXAcxHnhyXhA7CwW_r9iYNJZvI_Wjyyh5DlvuLzhpTIvwjqOHyF00RDj-wocOt0Tq9Kg0JUKWzGjS5N0sxJcTx0fqQRH-HN97gwLUMFHy/s640/Process.jpg" width="640" /></a></div>
<br />
<br />
Obwohl "UserRole" nirgendwo im Prozess ausgewertet oder geschrieben wird, wird diese Information im Hintergrund ausgewertet.<br />
<br />
Das heisst, die von der Testklasse erzeugten Daten sind nicht vollständig.<br />
Im Test werden einige Daten von einem on the fly erzeugten User generiert.<br />
Das User-Objekt wie folgt überarbeitet: <br />
<br />
<br />
<pre class="brush:java;">User obj = new User();
........
if(obj.UserRoleId == null) {
UserRole r = new UserRole(name = 'TEST ROLE');
Database.insert(r);
obj.UserRoleId = r.Id;
}
</pre>
<br />
Testklasse laufen lassen. Success.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-894650258904951362015-09-30T13:23:00.001+02:002015-09-30T13:23:51.740+02:00Neue Salesforce Zertifizierungen für Entwickler<br />
Ab September'15 führte Salesforce neue Zertifizierung für Entwickler ein:<br />
- Salesforce Certified Platform Developer I<br />
- Salesforce Certified Platform Developer II<br />
- Salesforce Certified Platform App Builder <br />
<br />
Die "Force.com Developer" und "Advanced Developer" Zertifizierungen existieren nicht mehr.<br />
Für
alle, die die Force.com Developer bereits gemacht haben und die
Advanced Developer machen wollten ist das sicherlich eine schlechte
Nachricht. Um die "Platform Developer II" (ehemalige Advanced Developer)
zu machen, wird die "Platform Developer I" benötigt.<br />
<br />
Das
heisst, statt einen Schritt nach vorne in der Qualifizierung zu machen,
machen wir einen Schritt zurück, und sind gezwungen, als erstes die
"Platform Developer I" zu absolvieren.<br />
<br />
Die bereits
erworbene "Force.com Developer" kann in die seit September eingeführte
"Platform App Builder" umgewandelt werden. Dazu bietet Salesforce die
sogenannte "Transition" Prüfung an, die 20 Fragen enthält und 30 Minuten
dauert.<br />
<br />
<br />
<b><u>Hier sind ein paar Themen/Fragen aus der "Platform App Builder - Transition" Zertifizierung:</u></b><br />
1) Was passiert beim Installieren von Unmanaged Packages?<br />
2) Benutzung von Record Types in Kombination mit Picklist Feldern?<br />
3) Was sind social Accounts? Wie werden sie in Salesforce benutzt?<br />
4) Validierungsregel greift nicht. Warum?<br />
5)
Eine oData Verbindung wird mit Lightning Connect eingerichtet. Was muss
berücksichtigt werden, wenn man Daten in Salesforce durchsuchen möchte?<br />
6) Welche Rules werden nach der Ausführung von "re-avaluated workflows" ausgeführt?<br />
7) Differenzierung der Sandbox-Typen<br />
8) Welche Feld-Typen werden für die Suche verwendet (Text, Picklist, Phone, Formula)?<br />
9) Was passiert beim Ändern von Feldtypen? Wann ist mit Datenverlust zu rechnen?<br />
10) Detaillierte Abfrage zu den Case Assignment Rules?<br />
11) Visualforce Seite ist in Salesforce1 nicht sichtbar. Warum?<br />
12)
Was kann mit Lightning App Builder auf einer Lightning Page
implementiert werden (Standard/Custom lightning components, Global
Publisher Actions, Custom Visualforce Components, Object-Specific
Publisher actions)?<br />
13) Unterschied zwischen Person und Business Accounts.<br />
<br />
<br />
<br />
Hier ist ein Auszug aus der Salesforce Certification Knowledge Base mit weiteren Details zu den neuen Prüfungen:<br />
<ul style="-webkit-text-stroke-width: 0px; background-color: #f8f8f8; border: 0px; color: black; font-family: Arial, Helvetica, sans-serif; font-size: 13px; font-stretch: inherit; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; list-style: disc; margin: 1em 1em 1em 40px; orphans: auto; padding: 0px; text-align: left; text-indent: 0px; text-transform: none; vertical-align: baseline; white-space: normal; widows: 1; word-spacing: 0px;">
<li style="border: 0px; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"><a href="http://www.salesforce.com/campaigns/success-services/certified-force-developers.jsp" style="border: 0px; color: #009ddc; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;" target="_blank">Transition path</a> for Salesforce Certified Force.com Developers</li>
<li style="border: 0px; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"><a href="http://www.salesforce.com/campaigns/success-services/advanced-force-developer-certification.jsp" style="border: 0px; color: #009ddc; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;" target="_blank">Transition path</a> for Salesforce Certified Force.com Advanced Developers</li>
<li style="border: 0px; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;"><a href="http://www.salesforce.com/campaigns/success-services/developer-certification-in-progress.jsp" style="border: 0px; color: #009ddc; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;" target="_blank">Transition path</a> for candidates who have passed the Salesforce Certified Force.com Advanced Developer multiple choice exam.</li>
</ul>
<br />
Die
bereits erworbenen Salesforce Zertifizierungen können ganz bequem über
"Certification Verification" abgefragt werden. Dazu die Seite <a href="http://certification.salesforce.com/verification">http://certification.salesforce.com/verification</a> öffnen, auf "Verification" klicken und den Namen oder Email-Adresse der gewünschten Person eingeben.<br />
Alternativ lässt sich der Name auch als Parameter mitgeben, z.B.<br />
<a href="http://certification.salesforce.com/verification?&fullname=Oleg%20Tuchscherer">http://certification.salesforce.com/verification?&fullname=Oleg%20Tuchscherer</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJQNMX-s7KkJnpKX20tZc1Du9sP_7OVSbETqy2XwEI42BsdTe771S0vhD9Thz1sWYv8ujm_J8W9yt8ALgHql8G_IsZs2MxvNiMmPscc_f9K-IZLgi-kGnUStMQpvnu5ioytmafBo4Dtx3h/s1600/Verification+2015-09-25+11-01-30.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="395" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJQNMX-s7KkJnpKX20tZc1Du9sP_7OVSbETqy2XwEI42BsdTe771S0vhD9Thz1sWYv8ujm_J8W9yt8ALgHql8G_IsZs2MxvNiMmPscc_f9K-IZLgi-kGnUStMQpvnu5ioytmafBo4Dtx3h/s640/Verification+2015-09-25+11-01-30.jpg" width="640" /></a></div>
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-25739923882358605772015-08-04T12:00:00.000+02:002015-08-04T12:00:08.351+02:00Kleine SOQL Aufgabe zum Aufwärmen<b>Beschreibung </b><br />
Aktuelle Währungsumrechnungskurse werden pro Tag in die Datenbank importiert.<br />
Beispiel:<br />
1 USD = 0,9121 EUR<br />
am 07.08.2015<br />
<br />
1 Russicher Rubel = 0,0145 EUR<br />
am 06.08.2015<br />
<br />
Es kann aber vorkommen, dass es keine Umrechnungskurse am aktuellen Tag zur Verfügung stehen.<br />
<br />
<b>Aufgabe</b><br />
Hole mit einer SOQL Abfrage alle aktuellen Umrechnungskurse zu allen Währungen. Falls kein Umrechnunskurs zum heutigen Tag zur Verfügung steht, soll der letzte Umrechnuskurs genommen werden.<br />
<br />
<br />
<b>Lösung</b><br />
Durch das Gruppieren von Währungscodes in Kombination mit der Aggregate-Funktion MAX() bekommt man alle relevanten Datensätze.<br />
<b><br /></b>
<pre class="brush:java;">for(sObject sobj:[ Select Id, currencyCode__c, MAX(validDate__c)
FROM CurrencyTable__c
WHERE validDate__c <= TODAY
GROUP BY currencyCode__c, Id ]){
String sCode = String.valueOf(sobj.get('currencyCode__c'));
String sId = String.valueOf(sobj.get('Id'));
// ..........
}
</pre>
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-2938479734061326532015-07-28T11:29:00.000+02:002015-07-28T11:49:22.686+02:00Sortieren von Listeneinträgen mit APEXEine Visualforce Seite enthält diverse Options-, Checkboxen-, Auswahlfelder deren Inhalt dynamisch vom Controller in Form von Listen <span style="color: blue;">list<SelectOption></span> aufgebaut wird.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2bhTfNTvlVeOsg5clqlRRFRVDkpp4FQu1VvQcgOdaCOLTy1wtUESiEXbql7cyFGjg-vV-IfNq9suAH9MX7ONr7r64A_SNP8MYhtSRLdRI96ktPJJeylATKT8A4vhE9Zp8yTH1RQbTmGI/s1600/managerViewFilter.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2bhTfNTvlVeOsg5clqlRRFRVDkpp4FQu1VvQcgOdaCOLTy1wtUESiEXbql7cyFGjg-vV-IfNq9suAH9MX7ONr7r64A_SNP8MYhtSRLdRI96ktPJJeylATKT8A4vhE9Zp8yTH1RQbTmGI/s1600/managerViewFilter.jpg" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2bhTfNTvlVeOsg5clqlRRFRVDkpp4FQu1VvQcgOdaCOLTy1wtUESiEXbql7cyFGjg-vV-IfNq9suAH9MX7ONr7r64A_SNP8MYhtSRLdRI96ktPJJeylATKT8A4vhE9Zp8yTH1RQbTmGI/s1600/managerViewFilter.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"> </a></div>
<br />
<br />
<br />
Die Einträge sind unsortiert. Dummerweise gibt es von Salesforce immer noch keine (brauchbare) Funktion zum Sortieren von SelectOptions nach Label. <br />
Die im Internet gefundenen Sort-Funktionen haben auch nur teilweise funktioniert. <br />
Abhinav Gupta hat in seinem Blog http://www.tgerm.com/2011/08/salesforce-apex-selectoption-sort.html eine simple Klasse vorgestellt, die ich letztendlich nach einer kleinen Modifikation: <br />
<pre name="code"><span style="color: blue;"><span style="background-color: white;"> opt.getLabel() +</span></span></pre>
ersetzt durch <br />
<pre name="code"><span style="color: blue;"> opt.getLabel().toLowerCase() + ' ' +</span></pre>
eingesetzt habe.<br />
<br />
<b>Aufruf:</b><br />
<pre class="brush:java;">
list<SelectOption> F_lstDepartment = new list<SelectOption>();
lstDepartment.add('id1', 'Dev'');
lstDepartment.add('id2', '---Please Choose---');
lstDepartment.add('id3', 'Marketing Services');
SelectOptionSorter.doSort(lstDepartment, SelectOptionSorter.FieldToSort.Label);
</pre>
<br />
<b>Klasse:</b><br />
<pre class="brush:java;">global class SelectOptionSorter {
/**
Sort field to use in SelectOption i.e. Label or Value
*/
global enum FieldToSort {
Label, Value
}
global static void doSort(List<selectoption> opts, FieldToSort sortField) {
if(opts != null){
Map<string selectoption=""> mapping = new Map<string selectoption="">();
// Suffix to avoid duplicate values like same labels or values are in inbound list
Integer suffix = 1;
for (Selectoption opt : opts) {
if (sortField == FieldToSort.Label) {
mapping.put( // Done this cryptic to save scriptlines, if this loop executes 10000 times
// it would every script statement would add 1, so 3 would lead to 30000.
(opt.getLabel().toLowerCase() + ' ' + suffix++), // Key using Label + Suffix Counter
opt);
} else {
mapping.put(
(opt.getValue() + suffix++), // Key using Label + Suffix Counter
opt);
}
}
List<string> sortKeys = new List<string>();
sortKeys.addAll(mapping.keySet());
sortKeys.sort();
// clear the original collection to rebuilt it
opts.clear();
for (String key : sortKeys) {
opts.add(mapping.get(key));
}
}
}
}
</pre>
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-90494926201943222015-07-20T08:46:00.002+02:002015-07-28T11:56:35.614+02:00Apex Klasse per Custom Button ansprechen<br />
Eine interessante Möglichkeit, eine APEX-Klasse per Custom Button anzusprechen, wird von Shivanath in seinem Artikel "<a href="http://blog.shivanathd.com/2014/07/call-apex-class-from-custom-button-salesforce.html" target="_blank">Call Apex Class from custom button (javascript) in Slaesforce</a>" ausführlich erläutert.<br />
<br />
<div style="-webkit-text-stroke-width: 0px; background-color: white; color: #666666; font-family: Glegoo, serif; font-size: 15.3999996185303px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21.5599994659424px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<b><u>Klasse:</u></b></div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; color: #666666; font-family: Glegoo, serif; font-size: 15.3999996185303px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21.5599994659424px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<pre class="brush: java" style="-webkit-text-stroke-width: 0px; background-color: white; color: #666666; font-size: 15.3999996185303px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21.5599994659424px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; widows: 1; word-spacing: 0px;">global class MyClass{
webservice static void myMethod() // you can pass parameters{
// Do something
}
}</pre>
<pre class="brush: java" style="-webkit-text-stroke-width: 0px; background-color: white; color: #666666; font-size: 15.3999996185303px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21.5599994659424px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; widows: 1; word-spacing: 0px;"> </pre>
<b><u>Custom Button :</u></b><b><u><br /></u></b></div>
<pre class="brush: java" style="-webkit-text-stroke-width: 0px; background-color: white; color: #666666; font-size: 15.3999996185303px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21.5599994659424px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; widows: 1; word-spacing: 0px;">{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")}
if({!AAA__c.Name}!=Null){
sforce.apex.execute("MyClass","myMethod",{}"});
alert("This is {!AAA__c.Name}");
}</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-38893290153664270832015-06-26T09:11:00.001+02:002015-06-26T11:23:06.844+02:00Lass dich inspirieren!Ein guter Kollege von mir hat mich neulich gefragt, ob ich Lust hätte, eine App für die Apple Watch mitzuentwickeln.<br />
„Genial! Super spannend!“.<br />
Nur womit fange ich bloß an? Da es ein ganz neues Thema für mich ist, fange ich an, die Infos zu sammeln, auszuwerten, zu filtern, auszuprobieren…<br />
Ein laaaaaanger und aufwändiger Prozess, der sich um ein Vielfaches verkürzen lässt, wenn man von einem kompetenten Ansprechpartner geführt wird.<br />
<br />
Mit dem gleichen Problem haben auch viele Salesforce Einsteiger zu tun. Und nicht nur sie! <br />
Salesforce wächst unermüdlich und rasant, stellt neue mächtige Werkzeuge zur Verfügung.<br />
Der richtige Umgang mit diesen Werkzeugen ist essentiell und muss gelernt werden.<br />
An dieser Stelle kommt der Hersteller ins Spiel!<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<b>Am 02.07.2015 kommt Salesforce nach München.</b><br />
<div class="separator" style="clear: both; text-align: center;">
<b> </b><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ2iAbwYioH-4Dtltyw68Nlc9uu3Cn4lChGckj4dw4PTFT1PFgcWapZ9NWF5aSgM9yLNjaFHiTxYSMe9fmkmTKfniLdCENJwlgyODDvXZ5LPQRDWlrrP4RRR8ZA3ERlsRFpV-Ihd8OFnv1/s1600/IMG_1653.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ2iAbwYioH-4Dtltyw68Nlc9uu3Cn4lChGckj4dw4PTFT1PFgcWapZ9NWF5aSgM9yLNjaFHiTxYSMe9fmkmTKfniLdCENJwlgyODDvXZ5LPQRDWlrrP4RRR8ZA3ERlsRFpV-Ihd8OFnv1/s1600/IMG_1653.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ2iAbwYioH-4Dtltyw68Nlc9uu3Cn4lChGckj4dw4PTFT1PFgcWapZ9NWF5aSgM9yLNjaFHiTxYSMe9fmkmTKfniLdCENJwlgyODDvXZ5LPQRDWlrrP4RRR8ZA3ERlsRFpV-Ihd8OFnv1/s320/IMG_1653.JPG" width="320" /></a></div>
Meine Kollegin, Michaela hat in ihrem Beitrag ausführlich erläutert, warum es sich lohnt, dabei zu sein: <a href="http://blog.factory42.com/4-gruende-anfang-juli-nach-muenchen-zu-kommen" target="_blank">Vier Gründe am 2. Juli nach München zu kommen</a>!<br />
<br />
Von Tobias gibt es einige Empfehlungen zu diesem Event: <a href="http://blog.factory42.com/saleforce-world-tour-7-tipps-zur-vorbereitung" target="_blank">Salesforce World Tour - 7 Tipps zur Vorbereitung</a>.<br />
<br />
Ein Tipp von mir: Salesforce stellt interessante Literatur kostenlos zur Verfügung. Dieser Stand befindet sich in der Haupthalle und wird gut besucht. Die Nachfrage ist groß! Nur wer zeitig da ist, bekommt alles stressfrei. Ich bin meistens um 8 Uhr da ;-)<br />
<br />
Für Entwickler liegt der Fokus primär auf „Lightning“ dieses Jahr.<br />
Interessante Präsentationen unter anderem dazu gibt es auf der <a href="https://www.salesforce.com/de/events/details/sfwt15-munich/developer-zone/" target="_blank">Developer Zone</a>.<br />
<br />
Meine Kolleginnen und Kollegen haben sich bereits mit Lightning auseinander gesetzt und ihre Erfahrungen fleißig geteilt:<br />
<br />
von Sabine<br />
<a href="http://blog.factory42.com/salesforce-lightning-schema-builder-teil1" target="_blank">Lightning Schema Builder – Einfacher am Datenmodell arbeiten</a> <br />
<a href="http://blog.factory42.com/salesforce-lightning-schema-builder-teil2" target="_blank">Lightning Schema Builder – Vergleich und Nutzungsempfehlung</a><br />
<br />
von Tobias<br />
<a href="http://blog.factory42.com/salesforce-lightning-process-builder-teil-1" target="_blank">Salesforce Lightning Process Builder Teil 1 - Automatisieren leicht gemacht</a><br />
<br />
von Moritz<br />
<a href="http://blog.factory42.com/lightning-connect-teil-1" target="_blank">Lightning Connect: Teil 1</a><br />
<a href="http://blog.factory42.com/lightning-connect-teil-2" target="_blank">Lightning Connect: Teil 2</a><br />
<br />
Es ist eine informative, einzigartige und entspannte Veranstaltung! <br />
Hier kannst du dem fast zwei Meter großen Top Manager persönlich die Hand schütteln.<br />
Komm mit und lass dich von Marc Benioff inspirieren!<br />
<br />
<br />
PS: auch dieses Jahr wird's bei uns gefeiert! Du bist gerne zu unserer <a href="http://blog.factory42.com/events/factory42-warmup-party-2015-der-countdown-hat-begonnen" target="_blank">Warmup Party</a> am 01.07. eingeladen! Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-26253377554745851772015-05-18T17:20:00.000+02:002015-05-18T17:20:26.322+02:00Batch aus Managed Package startenNach der Installation eines Managed Packages versuche ich einen Batch über die Developer Konsole auszuführen.<br />
Beim Aufruf muss das Präfix berücksichtigt werden.<br />
Allerdings erscheint nach dem Batch-Aufruf<br />
<pre>Database.executeBatch(new packagePrefix__BatchUpdateRecords());</pre>
die folgende Fehlermeldung<br />
Invalid type: packagePrefix__BatchUpdateRecords<br />
<br />
Lösung:<br />
benutze einen Punkt statt "__" als Trennzeichen zwischen Präfix und Batchname<br />
<br />
<pre>Database.executeBatch(new packagePrefix.BatchUpdateRecords());</pre>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-50510269039322547202015-04-20T12:00:00.000+02:002015-04-21T21:14:12.978+02:00Managed Package Installation bricht mit "Package Install Failed" abInstallation eines (von mir erstellten) Managed Packages schlägt fehl.<br />
Ich bekomme die folgende Email von Salesforce.<br />
<br />
<br />
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">Your request to install package "abc" was unsuccessful. None of the data or setup information in your <a href="http://salesforce.com/"><span class="s2">salesforce.com</span></a> organization was affected.</span></div>
<div class="p2">
<span style="background-color: white; color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">If your install continues to fail, contact Salesforce CRM Support through your normal channels and provide the following information.</span></div>
<div class="p2">
<span style="background-color: white; color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">Organization: def (00D24000000ZrBi)</span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">User: Oleg Tuchscherer (00524000000HCj8)</span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">Package: ghi (05zI0000000AzuU)</span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">Error Number: 370924781-27562 (-1283512546)</span></div>
<div class="p2">
<span style="background-color: white; color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">Package Install Failed</span></div>
<div class="p2">
<span style="background-color: white; color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">An error has occurred during a package install operation.</span></div>
<div class="p2">
<span style="background-color: white; color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="background-color: white; color: #666666;">Thank You</span><br />
<span class="s1" style="background-color: white; color: #666666;"><br /></span>
<span class="s1" style="background-color: white; color: #666666;"><br /></span></div>
<div class="p3">
<span class="s3" style="background-color: white;"><br /></span></div>
<div class="p3">
<span class="s3" style="background-color: white;">Die Email enthält keine Informationen über die Ursache. Da das Package hunderte von Design Elementen und tausende von Zeilen Code enthält, ist das unmöglich "den Übeltäter" zu finden.</span></div>
<div class="p3">
<span style="background-color: white;">Ein Case bei Salesforce (... hmm, soll ich mir das wirklich antun?!) löst das Problem auch nicht.</span></div>
<div class="p3">
<span style="background-color: white;"><br /></span></div>
<div class="p3">
<span style="background-color: white;">Mit einem kleinen Trick lässt sich das Problem in den Griff kriegen.</span></div>
<div class="p3">
<span style="background-color: white;">Bei der Installation von Managed Package muss der Parameter <b>&newui=1</b> angehängt werden, z.B.</span></div>
<div class="p3">
<span style="background-color: white;"><br /></span></div>
<table border="0" cellpadding="0" cellspacing="0" class="detailList"><tbody>
<tr><th class="labelCol vfLabelColTextWrap first last" scope="row"></th><td class="data2Col first last"><u><span style="color: blue;">https://login.salesforce.com/packaging/installPackage.apexp?p0=05zI0000000AzuU<b>&newui=1</b></span></u></td></tr>
</tbody></table>
<div class="p3">
<span class="s3" style="background-color: white;"><br /></span></div>
<div class="p3">
<span class="s3" style="background-color: white;">Die Installation schlägt zwar immer noch fehl, aber die Salesforce Email enthält entscheidende Informationen über die Fehlerursache, z.B.</span></div>
<div class="p3">
<span class="s3" style="background-color: white;"><br /></span>
<span class="s3" style="background-color: white;"><br /></span></div>
<div class="p1">
<span class="s1" style="color: #666666;">Your request to install package "abc" was unsuccessful. None of the data or setup information in your <span class="s2">salesforce.com</span> organization was affected.</span></div>
<div class="p2">
<span style="color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="color: #666666;">If your install continues to fail, contact Salesforce CRM Support through your normal channels and provide the following information.</span></div>
<div class="p2">
<span style="color: #666666;"><span class="s1"></span><br /></span></div>
<div class="p1">
<span class="s1" style="color: #666666;">Organization: def (00D24000000ZrBi)</span></div>
<div class="p1">
<span class="s1" style="color: #666666;">User: Oleg Tuchscherer (00524000000HCj8)</span></div>
<div class="p1">
<span class="s1" style="color: #666666;">Package: ghi (05zI0000000AzuU)</span></div>
<div class="p1">
<span class="s1" style="color: #666666;">Error Number: 163097831-31260 (2062720984)</span><br />
<span class="s1" style="color: #666666;"><br /></span></div>
<div class="p1">
<span class="s1" style="color: #666666;">Problem:</span></div>
<div class="p1">
<span class="s1" style="background-color: #fce5cd; color: #666666;">1. (folderXYZ/Report_4) Required field is missing: sourceValues</span></div>
<div class="p3">
<span class="s3" style="background-color: #fce5cd; color: #666666;">
</span></div>
<div class="p1">
<span class="s1" style="background-color: #fce5cd; color: #666666;">folderXYZ/Report_4: Required field is missing: sourceValues</span></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-68305630556703895002015-04-17T10:41:00.001+02:002015-04-17T13:06:37.053+02:00Salesforce APEX Techniken<h2>
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: small;">Mal auf die Schnelle zusammenbasteln</span></h2>
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">„Das kann doch nicht so schwer sein!“ Das ist vermutlich einer der berühmtesten Sätze, mit dem ein (Salesforce) Entwickler konfrontiert wird. </span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Diese Aussage wird vor allem als Waffe benutzt, um den vom Entwickler geschätzten Aufwand und die damit verbundenen Kosten zu reduzieren. Ein mutiger "Angreifer" mit wenig Entwicklungs- und Prozess-Know-how ergreift nicht zu selten die Initiative und stellt selbst triumphierend das Produkt seiner Wünsche her.</span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Es ist in der Tat nicht schwer, schnell das gewünschte Ergebnis zum Beispiel in Form eines Triggers zu erzielen. Im Internet kursieren viele Beispiele dazu. Die mächtige Salesforce Community unterstützt im Problemfall.</span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Einige Lösungen aus dieser Kategorie durfte ich in den letzten Jahren begutachten.</span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Sie alle haben eine Gemeinsamkeit: sie funktionieren nicht (lange)! Da fühlt man sich manchmal wie die Stiftung Warentest, die ein chinesisches Billigprodukt testet.</span><br />
<h2>
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: small;">Ziel als Ausgangspunkt</span></h2>
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Man muss sich nicht zwangsweise mit Begriffen wie Wiederverwendbarkeit oder Polymorphismus auseinandersetzen, um einen nachhaltig funktionierenden Code zu schreiben.</span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Es ist viel mehr die Fähigkeit, in die Zukunft zu blicken, um die Erkenntnisse über die zu verarbeitende Datenmenge in Kombination mit Salesforce Limits zu gewinnen.</span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Allerdings kommt ein Salesforce-Nostradamus mit diesen Erkenntnissen auch nicht weit, ohne geeignete Techniken der APEX-Programmierung zu kennen.</span><br />
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Die wichtigsten Techniken aus der APEX-Welt habe ich in Form einer Infografik zusammen gefasst.</span><br />
<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXuK8aNbs1q3FsSArqWxYsXtcFS6MTMA1pcwI647SBUNED3WWLjNwTJL6YMuJCbtljd8nU6mTBa7_IGsplg3xQpeHCvxwztX39AHm2tdtdSTF2-UWCQj_PpPoBI3fcZOI3FqKyE_c0mSu4/s1600/ApexVerarbeitung.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXuK8aNbs1q3FsSArqWxYsXtcFS6MTMA1pcwI647SBUNED3WWLjNwTJL6YMuJCbtljd8nU6mTBa7_IGsplg3xQpeHCvxwztX39AHm2tdtdSTF2-UWCQj_PpPoBI3fcZOI3FqKyE_c0mSu4/s1600/ApexVerarbeitung.jpg" height="640" width="580" /></a></div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-54425093070308937392015-03-12T14:57:00.000+01:002015-03-16T15:04:49.294+01:00Verarbeitung mit AggregateResult beschleunigen<br>
Verarbeitung großer Datenmengen in Salesforce kann unter Umständen viel Zeit in Anspruch nehmen. Sollte dieser Prozess im Vordergrund länger als 10 Sekunden dauern, wird er vom System gekillt. Mit diesem Problem hatte ich zu tun, als ich versuchte, ca. 30.000 Datensätze zu verarbeiten und die Ergebnisse in einem Chart (Visualforce Page) darzustellen.<br>
<br>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6-oESnB9xarHDlglvOlcUBtZU0iq4MYLOnfO4mfFbJ0ME5_MpQAavuNbreJs_SVOsAegedeCLrpe2_lwhyqm7GqGnJzVnVWLMjEhqiLvdSWlaGsnT7AzAzdzFr4aj_6nzSNPOrjd209Ul/s1600/chart.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6-oESnB9xarHDlglvOlcUBtZU0iq4MYLOnfO4mfFbJ0ME5_MpQAavuNbreJs_SVOsAegedeCLrpe2_lwhyqm7GqGnJzVnVWLMjEhqiLvdSWlaGsnT7AzAzdzFr4aj_6nzSNPOrjd209Ul/s1600/chart.jpg" height="170" width="640"></a></div>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<h3>
Vorhaben:</h3>
30.000 Datensätze per SOQL aus der Datenbank holen, verarbeiten, und die kumulierten Ergebnisse (s. Screenshot oben) in einem Chart sowie in einer Tabelle darstellen.<br>
<h3>
Problem und Ursache:</h3>
<div>
Die Verarbeitung von 30.000 Datensätzen dauert länger als 10 Sekunden. Somit wird dieser Prozess von System unterbrochen. Die folgende Fehlermeldung erscheint:</div>
<div>
<span style="background-color: #fff2cc; color: red;"><strong>Time limit exceeded</strong> - Your request exceeded the time limit for processing.</span></div>
<h3>
Lösung:</h3>
<div>
Mit dem Einsatz der folgenden Lösung konnte ich die Verarbeitungszeit von > als 10 Sekunden auf 0,1 Sekunden reduzieren.</div>
<div>
<br></div>
Falls kein Update von einzelnen Datensätzen notwendig ist, kann das Problem mit dem Einsatz des <b>AggregateResult</b> Standard Objektes gelöst werden.<br>
Das Objekt wird benutzt, um diverse Berechnungen von der Datenbank selbst durchführen zu lassen, und nur die Ergebnisse abzufragen. Dabei reduzierte sich die Anzahl der Ergebnisse in meinem Fall von 30.000 auf ca. 100 Stück. Einige Berechnungen aus dem Visualforce Page Controller mussten zwangsweise in neue Formelfelder ausgelagert werden.<br>
<br>
Folgendes muss berücksichtigt werden:<br>
- falls die entwickelte Lösung Bestandteil eines Managed Packages ist, muss das entsprechende Präfix in die Auswertung von AggregateResult Ergebnissen integriert werden (s. Screenshot, lila)<br>
- das Ergebnis einer Feldabfrage über Relation (s. Screenshot, rot) ist in der Auswertung ohne Relation verfügbar<br>
- Summen werden mit Variablen versehen<br>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbZUojKVDTqJ2VpH0pn0q84A0x7ZizbJHC4Isa39w0RkngEYYX3HA5lRMIn99UIKam0e8PbaBMqQJFtswTKwrrOnSzgdM6cJVMpWedr041A09Z6yP2k8k9gW6ZE8HCQTtg-7Zp3C6yxQr6/s1600/soql.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbZUojKVDTqJ2VpH0pn0q84A0x7ZizbJHC4Isa39w0RkngEYYX3HA5lRMIn99UIKam0e8PbaBMqQJFtswTKwrrOnSzgdM6cJVMpWedr041A09Z6yP2k8k9gW6ZE8HCQTtg-7Zp3C6yxQr6/s1600/soql.jpg" height="291" width="640"></a></div>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
Hilfreiche Informationen sind unter anderem hier zu finden:<br>
<a href="http://www.salesforce.com/us/developer/docs/soql_sosl/Content/sforce_api_calls_soql_select_agg_functions.htm">http://www.salesforce.com/us/developer/docs/soql_sosl/Content/sforce_api_calls_soql_select_agg_functions.htm</a><br>
<a href="http://blog.jeffdouglas.com/2010/04/12/using-aggregateresult-in-salesforce-com-soql/">http://blog.jeffdouglas.com/2010/04/12/using-aggregateresult-in-salesforce-com-soql/</a><br>
<br>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8432812501072503078.post-54137437069349938242015-03-03T12:35:00.000+01:002015-03-05T09:01:58.691+01:00SOQL Abfrage über mehr als 100.000 DatensätzeIn einigen Salesforce Instanzen kommt es regelmäßig vor, dass gigantische Datenmengen durchsucht werden müssen. Meistens übernehmen Trigger diese Arbeit, und in den meisten Fällen brechen sie die Arbeit mit der folgenden Fehlermeldung ab:<br />
<br />
<div class="p1">
<span style="color: red;"><b>System.QueryException: Non-selective query against large object type (more than 100000 rows)</b></span></div>
<br />
Die Ursache liegt in der Limitierung vom Heap Speicher, der bei über 100.000 zu durchsuchenden Datensätzen überläuft.<br />
<br />
Um dieses Problem zu lösen, muss der <b style="font-size: small;"><span style="color: #7f0055; font-family: Monaco;">WHERE-</span></b>Block mindestens ein indiziertes Feld enthalten,<br />
z.B. <i>customIndexedField__c = 'abc'</i><br />
Zusätzlich soll auf die Abfrage von NULL Werten verzichtet werden,<br />
z.B <i>customIndexedField__c != null</i><br />
<br />
Auszug aus der Salesforce Hilfe:<br />
<span style="background-color: white; color: #555555; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 13px;">The following fields are indexed by default: primary keys (Id, Name and Owner fields), foreign keys (lookup or master-detail relationship fields), audit dates (such as LastModifiedDate), and custom fields marked as External ID or Unique. </span><span style="color: #666666; font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: x-small;"><b>Nulls in the criteria prevented the use of indexes</b>, and some of the criteria was redundant and extended execution time. Design
the data model so that it does not rely on nulls as valid field values.</span><br />
<span style="background-color: white; color: #555555; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 13px;"><br /></span>
Es gibt allerdings ein Problem in Kombination mit Managed Packages<br />
****************************************************************<br />
<span style="color: red;">Nach der Installation eines managed Packages muss der Index manuell gesetzt werden! Dazu muss ein neues Ticket bei Salesforce aufgemacht werden, dass der Index defekt ist.</span><br />
Sieht so aus, als ob der Index nach der Installation eines managed Packages nicht aufgebaut wird. Salesforce hat bereits bestätigt, dass es ein Bug ist.<br />
****************************************************************<br />
<br />
In dem angehängten Video sieht man einen Trigger, der ein Lookup Feld aus einem managed Package beim Speichern eines Datensatzes abfragt. In diesem Fall kommt es zu der oben genannten Fehlermeldung.<br />
<br />
verursacht den Fehler:<br />
<b style="color: #7f0055; font-family: Monaco; font-size: small;">set<Id> setIdProjects = new set<Id>();</b><br />
Projekt Ids werden im Set <b style="color: #7f0055; font-family: Monaco; font-size: small;">setIdProjects </b>festgehalten<br />
<div class="MsoNormal">
<div style="margin-bottom: .0001pt; margin: 0cm;">
<span style="color: #7f0055; font-family: Monaco; font-size: x-small;"><b>List<Time__c> times = [SELECT Id </b></span><br />
<b style="color: #7f0055; font-family: Monaco; font-size: small;"> FROM Time__c</b><br />
<b style="color: #7f0055; font-family: Monaco; font-size: small;"> W</b><span style="color: #7f0055; font-family: Monaco; font-size: x-small;"><b>HERE prefix_Project__c=:</b></span><b style="color: #7f0055; font-family: Monaco; font-size: small;">setIdProjects</b><span style="color: #7f0055; font-family: Monaco; font-size: x-small;"><b>];</b></span><span style="font-family: Monaco; font-size: x-small;"> </span></div>
</div>
<div class="MsoNormal">
<span style="font-family: Monaco; font-size: 11pt;"><br /></span>
<br />
<br /></div>
<b><span style="color: #38761d;"><span style="font-size: large;">Lösung</span></span></b>:<br />
Wird statt Lookup-Feld aus dem Package ein neues Lookup- oder Textfeld mit External ID genommen, funktioniert der Trigger.<br />
* Das Textfeld ist als "External ID" markiert.<br />
<div>
<br />
<b style="color: #7f0055; font-family: Monaco; font-size: small;">set<</b><span style="background-color: yellow; font-family: Monaco; font-size: x-small;"><b><span style="color: purple;">String</span></b></span><b style="color: #7f0055; font-family: Monaco; font-size: small;">> setIdProjects = new set<<span style="background-color: yellow;">String</span>>();</b><br />
Projekt Ids werden im Set <b style="color: #7f0055; font-family: Monaco; font-size: small;">setIdProjects </b>als Strings festgehalten</div>
<div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; text-autospace: none;">
<span style="color: #7f0055; font-family: Monaco; font-size: x-small;"><b>List<Time__c> times = [SELECT Id </b></span><br />
<b style="color: #7f0055; font-family: Monaco; font-size: small;"> FROM Time__c</b><br />
<b style="color: #7f0055; font-family: Monaco; font-size: small;"> W</b><span style="color: #7f0055; font-family: Monaco; font-size: x-small;"><b>HERE Project_TXT__c=:</b></span><b style="color: #7f0055; font-family: Monaco; font-size: small;">setIdProjects</b><span style="color: #7f0055; font-family: Monaco; font-size: x-small;"><b>];</b></span><span style="font-family: Monaco; font-size: x-small;"> </span><span style="font-family: Monaco; font-size: 11pt;"> </span></div>
<div class="MsoNormal">
<br />
<b>ACHTUNG: <span style="color: #7f0055; font-family: Monaco; font-size: x-small;">setIdProjects </span>darf keine NULL Werte enthalten! </b></div>
<div class="MsoNormal">
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: center;">
<span style="font-size: large;"><iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/RRHnzdV4VQY/0.jpg" frameborder="0" height="266" src="http://www.youtube.com/embed/RRHnzdV4VQY?feature=player_embedded" width="320"></iframe></span></div>
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; text-autospace: none;">
<span style="font-family: Monaco; font-size: 11pt;"> </span></div>
<div class="MsoNormal">
<o:p></o:p></div>
<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]-->
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>DE</w:LidThemeOther>
<w:LidThemeAsian>JA</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
<w:UseFELayout/>
</w:Compatibility>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
DefSemiHidden="true" DefQFormat="false" DefPriority="99"
LatentStyleCount="276">
<w:LsdException Locked="false" Priority="0" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" Priority="39" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" Name="toc 9"/>
<w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" Priority="10" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" Priority="11" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" Priority="22" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="59" SemiHidden="false"
UnhideWhenUsed="false" Name="Table Grid"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]-->
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:Cambria;
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;}
</style>
<![endif]-->
<!--StartFragment-->
<!--EndFragment--><br />
<div class="MsoNormal">
<br /></div>
Unknownnoreply@blogger.com0