[Salesforce]オブジェクトのレコードタイプIDからレコードタイプ名取得

オブジェクトのレコードタイプIDからレコードタイプ名取得例を紹介します。

  List<RecordType> recordTypeList = [
    SELECT Id
      , Name
      FROM RecordType
      WHERE SobjectType = 'testObj__c'
      AND Id = '012211111111111111'
  ];

for(RecordType rtobj : recordTypeList){
    system.debug('rtobj.Name:'+rtobj.Name);
}

または、以下の例もあります。

String searchObjName = 'testObj__c';
String searchRecordTypeId = '012211111111111111';
List<RecordType> recordTypeList = [
    SELECT Id
      , Name
      FROM RecordType
      WHERE SobjectType  = : searchObjName
      AND Id = : searchRecordTypeId
  ];

for(RecordType rtobj : recordTypeList){
    system.debug('rtobj.Name:'+rtobj.Name);
}

[Salesforce]Failed to run tests synchronously.: Your query request was running for too long.

テストクラス実行時、「Failed to run tests synchronously.: Your query request was running for too long.」エラーの対応

Summary
Test classes failing with QUERY_TIMEOUT Failed to run tests synchronously when running in synchronous mode

  1. Login to the org which has quite number of managed package apex classes.
  2. Run the Apex Test Class from Developer Console in Sync Mode
  3. You may notice below exception when running the apex test class:

Error Message:

“QUERY_TIMEOUT Failed to run tests synchronously: Your query request was running for too long”

Workaround
As a workaround, please try to run the test class in asynchronous mode.

[Salesforce]lightning-record-form を使用して取引先責任者を作成

lightning-record-form を使用して取引先責任者を作成例を紹介します。

contactCreator.html

<template>
    <lightning-card>
        <lightning-record-form
            object-api-name={objectApiName}
            fields={fields}
            onsuccess={handleSuccess}>
        </lightning-record-form>
    </lightning-card>    
</template>

contactCreator.js

import { LightningElement } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import CONTACT_OBJECT from '@salesforce/schema/Contact';
import FIRSTNAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LASTNAME_FIELD from '@salesforce/schema/Contact.LastName';
import EMAIL_FIELD from '@salesforce/schema/Contact.Email';
export default class ContactCreator extends LightningElement {
    objectApiName = CONTACT_OBJECT;
    fields = [FIRSTNAME_FIELD, LASTNAME_FIELD, EMAIL_FIELD];
    handleSuccess(event) {
        const toastEvent = new ShowToastEvent({
            title: "Contact created",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(toastEvent);
    }    
}

contactCreator.js-meta.xml 

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
    </targets>
</LightningComponentBundle>

設定 をクリックして [設定] を選択します。
[クイック検索] ボックスに「Lightning アプリケーションビルダー」(Lightning App Builder)と入力し、[Lightning アプリケーションビルダー] を選択します。

Lightning ページを作成します。

[新規] (New)をクリックします。
[アプリケーションページ] (App Page)を選択し、[次へ] をクリックします。
[表示ラベル] に「Working with Data」(データの操作) と入力し、[次へ] をクリックします。
レイアウトで [ヘッダーと左サイドバー] (Header and Left Sidebar)を選択します。
[完了] (Finish)をクリックします。

contactCreator コンポーネントをページサイドバーにドラッグします。

ページを保存(Save)します。
ページを有効化します。デフォルトのアプリケーション名 (Working with Data) のままで [保存] (Save)をクリックします。
ページをナビゲーションメニューに追加するように要求されたら、[完了] (Finish)をクリックします。


新しいページを開きます。アプリケーションランチャーの検索で「work」と入力し、[Working with Data (データの操作)] を選択します。

データを登録します。

First name: Lisa
Last name: Jones
Email: ljones@developer.com

[Salesforce]レコードタイプ取得方法

レコードタイプ取得方法について紹介します。

SOQLから取得する方法

List<RecordType> rtList = [
    Select Id, Name, DeveloperName 
    From RecordType
    WHERE SobjectType='Account'];
for (RecordType rt : rtList) {
    system.debug('rt.Id:'+rt.Id);    // レコードタイプID
    system.debug('rt.Name:'+rt.Name);    // レコードタイプラベル名
    system.debug('rt.DeveloperName:'+rt.DeveloperName);   // レコードタイプAPI名
}

[Salesforce]Failed to load data Log from Salesforce.com: Salesforce automatically deletes system logs 24 hours after they’re generated. If the log you had open was less than 24 hours old, someone deleted it. To save logs, select File > Download Log.

「Failed to load data Log from Salesforce.com: Salesforce automatically deletes system logs 24 hours after they’re generated. If the log you had open was less than 24 hours old, someone deleted it. To save logs, select File > Download Log.」エラー対応方法例を紹介します。

エラー

解決法の一つの例

DeveloperConsoleFix.page作成

<apex:page docType="html-5.0" id="thepage">
  <script src="//cdnjs.cloudflare.com/ajax/libs/jsforce/1.7.0/jsforce.min.js"></script>
  
  <p>
Yes, "Delete my IDEWorkspace" sounds a little scary. But that's actually what this script will do.
The developer console state is maintained in a record in table IDEWorkspace. 
When that record is deleted, there is no state. If the dev
console decides to save something, it notices that and creates a new record.
  </p>
  
  <p>
This is not really documented anywhere. You can learn a little bit by reading
the Salesforce help article <a href="https://help.salesforce.com/articleView?id=000205964&language=en_US&type=1">Developer Console menus not working</a>
The API we are using is the 
<a href="https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/">Tooling API</a>. 
The documentation merely notes that "The following
Tooling API objects are used internally by the Developer Console."

  </p>
  
  <apex:form id="theform">
  <apex:pageblock id="thepageblock">
  <apex:pageblockButtons location="top" id="buttons">
    <apex:commandButton value="Delete my IDEWorkpace" 
        onclick="deleteIDEWorkspace()"
        disabled="True"
        id="deletebutton"
     />
  </apex:pageblockButtons>  
  <apex:pageBlockSection id="section">
    <apex:pageblocksectionitem id="item1">
        <apex:outputlabel value="IDEWorkspace ID:" styleclass="bold"/>
        <apex:outputtext value="not found" id="IdDisplay" />
    </apex:pageblocksectionitem>

  </apex:pageBlockSection>
  </apex:pageblock>
  </apex:form>
  
  <apex:outputPanel id="emptypanel">
  </apex:outputPanel>

  <script>
      var conn = new jsforce.Connection({ accessToken: '{!$Api.Session_Id}' });
      var workspaceId;
      var deleted = false;
      var button = document.getElementById('{!$Component.thepage.theform.thepageblock.buttons.deletebutton}');
      var notFoundMessage = 'No IDEWorkspace found for your user';
      
      var idDisplay = document.getElementById('{!$Component.thepage.theform.thepageblock.section.item1.IdDisplay}');

      conn.tooling.query("select id, name, createdbyid from ideworkspace where createdbyid = '{!$User.Id}'", 
          function(err, result) {
              if (err) { alert(err); }
              else if (result.totalSize > 1) {
                  alert('Query returned multiple IDEWorkspaces ' + JSON.stringify(result));
              }
              else if (result.totalSize < 1) {
                  idDisplay.innerHTML =  notFoundMessage;
              }
              else {
                  // exactly one IDEWorkspace found for this user
                  
                  workspaceId = result.records[0].Id;
                  console.log(workspaceId);
                  button.className = "btn";
                  button.disabled = false;
                  document.getElementById('{!$Component.thepage.theform.thepageblock.section.item1.IdDisplay}').innerHTML =  workspaceId;
              }
      });

      
      function deleteIDEWorkspace() {
      
        conn.tooling.query("select id, name, createdbyid from ideworkspace where createdbyid = '{!$User.Id}'", 
            function(err, result) {
              if (err) { alert(err); }
              else if (result.totalSize > 1) {alert('Query returned multiple IDEWorkspaces ' + JSON.stringify(result));}
              else if (result.totalSize < 1) {alert('Could not determine Id of your IDEWorkspace');}
              else {
                  console.log(workspaceId);
                  console.log("deleting...");
                  conn.tooling.sobject('IDEWorkspace').delete(workspaceId, function(err, ret) {
                      if (err || !ret.success) { return console.error(err, ret); }
                      alert('Deleted IDEWorkspace Successfully : ' + ret.id);
                      button.className = "btnDisabled";
                      button.disabled = false;
                  });
              }
        });
      }


  </script>

</apex:page>

参考URL:https://github.com/bolaurent/salesforce-developer-console-fix/blob/master/DeveloperConsoleFix.page

上記のVisualforceページ表示する。

https://{インスタンス}/apex/DeveloperConsoleFix

「Delete my IDEWorkspace」ボタン押下する。

ボタン押下後いかのように表示されます。

もちろん、開発者コンソール押下したら、今回のエラーは出ないはずです。

[Salesforce]NO_MASS_MAIL_PERMISSION, Single email is not enabled for your organization or profile.


「NO_MASS_MAIL_PERMISSION, Single email is not enabled for your organization or profile.」エラー対応方法を紹介します。

Setup > Email Administration > Deliverability. にして、

「全てのメール」へ変更

[Salesforce]SINGLE_EMAIL_LIMIT_EXCEEDED、「The daily limit for the org would be exceeded by this request」

SINGLE_EMAIL_LIMIT_EXCEEDED、「The daily limit for the org would be exceeded by this request」エラー時の制限値確認手順を紹介します。

  1. 制限を検証する組織にログインしていることを確認します。
  2. https://workbench.developerforce.com/login.php へアクセスします。
  3. すべての oauth プロンプトを受け入れて認証を完了します。
  4. [Jump to] 選択リストで [REST Explorer] を選択します。
  5. [Select] を選択します。
  6. 6. 表示されるオプションから、/services/data/vXX.0/limits を選択します。
  7. [Execute] をクリックします。
  8. SingleEmail 領域を選択すると、一日の最大呼び出し数と残りの呼び出し数が表示されます。

[Salesforce]生年月日(誕生日)から年齢の算出

生年月日(誕生日)から年齢の算出する数式項目作成例を紹介しまます。

IF(OR(MONTH(today())-MONTH(Birthday__c)>0,AND(MONTH(TODAY()) - MONTH(Birthday__c)>=0,DAY(TODAY()) - DAY(Birthday__c)>=0)),
YEAR(TODAY()) - YEAR(Birthday__c),
YEAR(TODAY()) - YEAR(Birthday__c)-1)

ここで、

Birthday__c : 誕生日の日付項目

[Salesforce]TestVisible アノテーション

TestVisible アノテーションにつついて紹介します。

TestVisible アノテーションを使用すると、テストクラス外にある別のクラスの非公開メンバーまたは保護メンバーにテストメソッドからアクセスできるようになります。これらのメンバーには、メソッド、メンバー変数、内部クラスが含まれます。このアノテーションは、テストを実行する目的でのみ、権限の高いアクセスレベルを有効にします。このアノテーションによって、非テストクラスからアクセスするメンバーの表示が変わることはありません。

このアノテーションでは、メソッドのアクセス修飾子やメンバー変数にテストメソッドでアクセスする場合に、それらを public に変更する必要はありません。たとえば、外部クラスに対して非公開メンバー変数を表示せずに、テストメソッドからアクセスできるようにする場合は、TestVisible アノテーションを変数定義に追加します。

この例では、非公開クラスメンバー変数と非公開メソッドに TestVisible アノテーションを付加する方法を示します。

public class TestVisibleExample {    
// Private member variable    
@TestVisible private static Integer recordNumber = 1;&nbsp;    
// Private method    
@TestVisible private static void updateRecord(String name)
 {        // Do something    }
}    

上記のクラスを使用するテストクラスを次に示します。アノテーションが付加されたメンバー変数とメソッドにアクセスするテストメソッドが含まれています。

@isTest
private class TestVisibleExampleTest {    
@isTest static void test1() {        

// Access private variable annotated with TestVisible        

Integer i = TestVisibleExample.recordNumber;        

System.assertEquals(1, i);         

// Access private method annotated with TestVisible        TestVisibleExample.updateRecord('RecordName');       

 // Perform some verification    

}