I have mini project for salesforce intership, so d did this code:
for(Integer i = 0; i < records; i++) {
Contact cont = new Contact(
FirstName = 'Name' + i,
LastName = 'Surname' + i,
Email = 'e' + i + '#mail.com'
);
if(i < 65) {
cont.AccountId = accA.Id;
cont.Contact_Level__c = 'Primary';
} else if(i < 130) {
cont.AccountId = accB.Id;
cont.Contact_Level__c = 'Secondary';
} else {
cont.AccountId = accC.Id;
cont.Contact_Level__c = 'Tertiary';
}
testContactList.add(cont);
}
insert testContactList;
}
And mistake is Variable does not exist: Contact_Level__c
But i really don't know what the matter.
Do you really have a field with that name on Contact table? No typos? Maybe it's called ContactLevel__c or Level__c?
Go to setup -> customize -> contacts -> fields (or Setup -> Object manager -> Contact -> fields if you're in Lightning) and double check?
This error occurs when the API name (ContactLevel__c) you mentioned in the code is not right means there may be typo mistake or the variable does not even exist.
You can go to Setup --> Object Manager --> Contact --> Fields and Relationship and search for the field, if the field is present copy the API name and paste it into the code.
Hope this solves your problem.
Related
As per the code I don't want to delete 0th record and delete rest of the record. But it is deleting all the records!
Kindly assist where I am making the mistake.
Here is the code:
list<account> scope = [Select Id,(Select id,CreatedDate,ebMobile__FileType__c,ebMobile__Account__c from Files__r order by CreatedDate DESC) from account where id in ('0016D00000444','0016D000000ugO')];
Set<Id>OldIds = new Set<Id>();
Set<Id>newIds = new Set<Id>();
Set<Id> rIds = new Set<Id>();
Set<Id> rrIds = new Set<Id>();
list<File__c> listmemb = new list<File__c>();
List<File__c> listmemb3 = new List<File__c>();
List<File__c> listmemb4 = new List<File__c>();
for(Account Acc : scope)
{
for(File__c fi : Acc.ebMobile__Files__r)
{
listmemb = [select id,CreatedDate,ebMobile__FileType__c from File__c where id =: fi.id];
if(fi.ebMobile__Account__c != Null)
{
for(Integer i=0; i<listmemb.size(); i++)
{
if(fi.ebMobile__FileType__c == 'Signature' && i==0)
{
rIds.add(listmemb[0].id); // Exclude 0th record
}
if(i>0 && listmemb[i].ebMobile__FileType__c == 'Signature' || i > 0 && listmemb[i].ebMobile__FileType__c != 'signature')
{
rrIds.add(listmemb[i].id); // Delete all record excluding 0th record
}
if(fi.ebMobile__FileType__c != 'Signature')
{
OldIds.add(fi.id);
}
}
}
}
}
listmemb3 = [Select id,CreatedDate,ebMobile__FileType__c from File__c where id in : OldIds];
listmemb4 = [Select id,CreatedDate,ebMobile__FileType__c from ebMobile__File__c where id in : rrIds];
if(listmemb3.size() > 0 && listmemb4.size()>0)
{
delete listmemb3;
delete listmemb4;
}
}
There are some many unnecessary checks and lists in the code
Let us simplify the stuff:
list scope = [Select Id,(Select id,CreatedDate,ebMobile__FileType__c,ebMobile__Account__c from Files__r order by CreatedDate DESC) from account where id in ('XXXXXXXXXXXXXXXX','XXXXXXXXXXXXXXXX')];//Always keep Ids encrypted while posting on public platform
SetOldIds = new Set();
SetnewIds = new Set();
Set rIds = new Set();
Set rrIds = new Set();
list listmemb = new list();
List listmemb3 = new List();
List listmemb4 = new List();
for(Account Acc : scope)
{
Integer i= 0; //This will be used to exclue the first element
for(File__c fi : Acc.ebMobile__Files__r)
{
//listmemb = [select id,CreatedDate,ebMobile__FileType__c from File__c where id =: fi.id];//You don't need this as you already have fi
//if(fi.ebMobile__Account__c != Null)We are getting fi from Acc so it won't be having ebMobile__Account__c as null, assuming it as lookup
//{
//for(Integer i=0; i {This is syntactically wrong
/* This whole section is not needed as rIds is not being used anywhere
if(fi.ebMobile__FileType__c == 'Signature' && i==0)
{
rIds.add(listmemb[0].id); // Exclude 0th record
}
*/
//if(i>0 && listmemb[i].ebMobile__FileType__c == 'Signature' || i > 0 && listmemb[i].ebMobile__FileType__c != 'signature')
if( i > 0 ) //Just put the check you need
{
rrIds.add(listmemb[i].id); // Delete all record excluding 0th record
}
if(fi.ebMobile__FileType__c != 'Signature')
{
OldIds.add(fi.id);
}
i++;
//}
//}
}
}
listmemb3 = [Select id,CreatedDate,ebMobile__FileType__c from File__c where id in : OldIds];
listmemb4 = [Select id,CreatedDate,ebMobile__FileType__c from ebMobile__File__c where id in : rrIds];
if(listmemb3.size() > 0 && listmemb4.size()>0)
{
delete listmemb3;
delete listmemb4;
}
}
Hope this helps.
#Vishal there are a couple things I'm not really sure of based on your code and context:
What defines 'the first file'? In your second (duplicate) query you don't seem to apply any ordering, so Salesforce might return you the same records in different order based on their database structuring. In your first sub-select query there is.
Is there a specific reason you use if, if, if, instead of if, else if, else if? With this approach you prevent the second and third item to run, even when the first one applied. This will simplify your code as you don't need all duplicate check (i == 0, i > 0 and such)
How is it possible that a different Salesforce record (File vs. ebMobile__File__c) can have the same Salesforce ID? (in your query for listMembers)
Couple suggestions:
Only query the records you really want to delete using Offset (shift starting record)
Please try to avoid doing queries and DML actions in loops, since this is bad for performance, but also might cause running into governor limits
Apply usage of variableBinding, this will ensure no SOQL Injection can be applied (when the account IDs are e.g. fetched from the front-end)
Simplify your logic to do what you really want; if you query only those to delete (see 1.) then you can simply loop ones to determine the Signature condition and then just delete the list of Files per Account. In my perspective, there is no need to query the files again, since you already have their IDs and records, so you can simply specify to delete the retrieved records, right?
Set<Id> accountIds = new Set<Id>{ 'xxxx', 'xxxx' };
List<Account> scope = [SELECT Id,
( SELECT Id, ...
FROM Files__r
ORDER BY CreatedDate DESC
OFFSET 1 )
FROM Account
WHERE Id IN :accountIds];
List<File> filesToDelete = new List<File>();
List<ebMobile__File__c> ebMobileFileToDelete = new List<File>();
for( Integer i = 0, j = scope.size(); i < j; i++ ){
Account acc = scope[ i ];
if( acc.Files__r != null & !acc.Files__r.isEmpty() ){
for( Integer k = 0, l = acc.Files__r.size(); k < l; k++ ){
File f = acc.Files__r[ k ];
if( f.ebMobile__FileType__c != 'Signature' ){
// When not signature, delete the original file
filesToDelete.add( f );
} else{
// Don't delete the File, but delete the EB MobileFile
ebMobileFileToDelete.add( new ebMobile__File__c( Id = f.Id ) );
}
}
}
}
if( !filesToDelete.isEmpty() ){ delete filesToDelete; }
if( !ebMobileFileToDelete.isEmpty() ){ delete ebMobileFileToDelete; }
Please note, I haven't run this code, so it might require some tweaking, but I hope you'll be able to get it all working.
Good luck and enjoy! Reinier
I have a spreadsheet that is continually being updated. On Tuesday Afternoons, I want to receive a report via email of rows with a certain column that is blank. For example, if C1:C100 is blank, I want an email of the entire pasted row.
I saw a previous question that helped, but I still need some guidance. I am very new to writing scripts. Essentially, I want to be able to use it as a reporting tool. So a specific person does not need to open up the doc and can delegate appropriately.
Also, another script that could possibly send an email with the spreadsheet once all the rows are completed.
Google App Script to trigger email
Send Email when value changes in Google Spreadsheet
Thanks!
Not sure about your specifics, but here is a general skeleton:
function onTuesdays() {
var s = SpreadsheetApp.getActiveSheet();
var firstRow = 3; // Specify the first row that data can be in.
var column;
var rowComplete;
var rows = [];
var recipients = 'something#something.com';
var subject = 'Tuesday Afternoon Report';
var message = '';
for (var i = firstRow; i <= s.getLastRow(); i++) {
column = 1;
rowComplete = true;
do {
if (s.getRange(i, column).isBlank()) {
rows.push(i);
rowComplete = false;
}
else column++;
}
while (column <= s.getLastColumn() && rowComplete);
}
if (rows.length == 0) message += 'There were no empty cells this week.';
else {
message += 'The following rows had empty cells this week:<ul>';
for (var i = 0; i < rows.length; i++) message += '<li>' + rows[i] + '</li>';
message += '</ul>';
}
MailApp.sendEmail(recipients, subject, message);
}
I'm not sure how you want the information to be displayed, but that should give you a general start.
Hope this helps!
I think that you can use the Code writed before and add a Trigger Event that send you and Email automatically.
Read the section: https://developers.google.com/apps-script/managing_triggers_programmatically
I have a trigger that moves the values from one object to another, but am stuck on how to move the values of the lookup fields from one to the other. what is the syntax? If you could show me the Company and the Chair_Rep ones that would be great!
<Lead> newLeadsList= new List<Lead>();
for (integer i=0; i<newContacts.size(); i++) {
if (newContacts[i].createlead__c == TRUE && oldContacts[i].createlead__c == FALSE ) {
newLeadsList.add(new Lead(
firstName = newContacts[i].firstName,
lastName = newContacts[i].lastName,
***Company = newContacts[i].account.name,***
Status = 'identified',
LeadSource = newContacts[i].leadsource ,
Product_Interest__c = 'CE',
//ContactLink__c = newContacts[i].ID,
Title = newContacts[i].title,
Email = newContacts[i].email,
//***Chair_Rep__c = newContacts[i].Chair_Rep__c***
Phone = newContacts[i].Phone,
MobilePhone = newContacts[i].MobilePhone,
// Address = newContacts[i].MailingAddress,
//Website = newContacts[i].Website,
nickname__c = newContacts[i].Nickname__c
Lookup fields should contain references (IDs) on records.
Is 'Company' a standard Lead field in your code?
***Company = newContacts[i].account.name,***
If so, then it's a Text(255) type field, which cannot be used as lookup.
If you need to make a lookup on a Contact's account record, then you can create a custom Lookup field on Lead with reference to Account. And then you could try this code (assuming ContactCompany is that custom lookup field :
ContactCompany__c = newContacts[i].AccountId
or
ContactCompany__c = newContacts[i].Account.Id
Chair_Rep__c and newContacts.Chair_Rep__c should be lookup fields on same object. Then this
Chair_Rep__c = newContacts[i].Chair_Rep__c
or this should work
Chair_Rep__c = newContacts[i].Chair_Rep__r.Id
I have a piece of code in an image sortable grid which sends back a resulting string array of integers based on the user's new sort order for 'propid':
{ 'imgid': '4,2,3,5,6,7,8,9,1','propid':'391' }
The above shows 9 images on the screen. The db image table has both an image id (imgid) field and a sort sequence field (orderseq). I am using a custom namespace datatype:
< connection.Get< ALocal.propimage >()
like all datatype connections in C1.
In direct SQL I would write this:
string []q = imgid.Split(',');
string qry="";
for (int i = 0; i < q.Length; i++)
{
qry += "update ALocal_propimage set propimage_orderseq="+(i+1)+" where prop_id="+propid+" and propimage_id="+q[i]+" ;";
}
sqlHelper obj = new sqlHelper();
obj.ExecuteNonQuery(qry);
return "Record Updated";
How does this convert to writing it using c# into Composite's C1 CMS 'Updating Multiple Data' method as I keep failing at it?
The C1 site 'Updating Multiple Data' method rudimentary example is:
using (DataConnection connection = new DataConnection())
{
var myUsers = connection.Get<Demo.Users>().Where (d => d.Number < 10).ToList();
foreach (Demo.Users myUser in myUsers)
{
myUser.Number += 10;
}
connection.Update<Demo.Users>(myUsers);
}
Any help would be really appreciated.
You would need to split your update code into a get and a update, to let C1 know exactly which entity you would like to update. So something like this
for (int i = 0; i < q.Length; i++)
{
var propimages = connection.Get<ALocal.propimage>().Where(o => o.PropId = propid && p.PropImageId = q[i]);
foreach (var o in propimages)
{
o.OrderSeq = i + 1;
}
connection.Update(propimages);
}
I am trying to determine a way to audit which records a given user can see by;
Object Type
Record Type
Count of records
Ideally would also be able to see which fields for each object/record type the user can see.
We will need to repeat this often and for different users and in different orgs, so would like to avoid manually determining this.
My first thought was to create an app using the partner WSDL, but would like to ask if there are any easier approaches or perhaps existing solutions.
Thanks all
I think that you can follow the documentation to solve it, using a query similar to this one:
SELECT RecordId
FROM UserRecordAccess
WHERE UserId = [single ID]
AND RecordId = [single ID] //or Record IN [list of IDs]
AND HasReadAccess = true
The following query returns the records for which a queried user has
read access to.
In addition, you should add limit 1 and get from record metadata the object type,record type, and so on.
I ended up using the below (C# using the Partner WSDL) to get an idea of what kinds of objects the user had visibility into.
Just a quick'n'dirty utility for my own use (read - not prod code);
var service = new SforceService();
var result = service.login("UserName", "Password");
service.Url = result.serverUrl;
service.SessionHeaderValue = new SessionHeader { sessionId = result.sessionId };
var queryResult = service.describeGlobal();
int total = queryResult.sobjects.Count();
int batcheSize = 100;
var batches = Math.Ceiling(total / (double)batcheSize);
using (var output = new StreamWriter(#"C:\test\sfdcAccess.txt", false))
{
for (int batch = 0; batch < batches; batch++)
{
var toQuery =
queryResult.sobjects.Skip(batch * batcheSize).Take(batcheSize).Select(x => x.name).ToArray();
var batchResult = service.describeSObjects(toQuery);
foreach (var x in batchResult)
{
if (!x.queryable)
{
Console.WriteLine("{0} is not queryable", x.name);
continue;
}
var test = service.query(string.Format("SELECT Id FROM {0} limit 100", x.name));
if(test == null || test.records == null)
{
Console.WriteLine("{0}:null records", x.name);
continue;
}
foreach (var record in test.records)
{
output.WriteLine("{0}\t{1}",x.name, record.Id);
}
Console.WriteLine("{0}:\t{1} records(0)", x.name, test.size);
}
}
output.Flush();
}