EclipseのForce.comでSalesforceのLightningコンポーネントを開発するためのForce.comのバージョンは以下です。
Force.com IDE v37.0とその以降バージョン
参考URL
https://developer.salesforce.com/docs/atlas.en-us.eclipse.meta/eclipse/eclipse_lightning_setup.htm
kinkun's blog
EclipseのForce.comでSalesforceのLightningコンポーネントを開発するためのForce.comのバージョンは以下です。
Force.com IDE v37.0とその以降バージョン
参考URL
https://developer.salesforce.com/docs/atlas.en-us.eclipse.meta/eclipse/eclipse_lightning_setup.htm
Lightning Design Systemを使ってVisualforceでLightning雰囲気のページ作成するのを共有する。
現在Salesforceの主なページ作成はVisualforceページですが、Salesforceが提供しているCSSフレームワーク Lightning Design System を使ってみる。
開発コンソル画面を開き、Visualforce ページ作成する。
<apex:page showHeader="false" standardStylesheets="false" sidebar="false" applyHtmlTag="false" applyBodyTag="false" docType="html-5.0">
  <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" lang="ja">
    <head>
      <meta charset="utf-8" />
      <meta http-equiv="x-ua-compatible" content="ie=edge" />
      <title>Salesforce Lightning Design System</title>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <!-- Import the Design System style sheet -->
      <apex:slds />
    </head>
 
    <apex:remoteObjects >
      <apex:remoteObjectModel name="Contact" fields="Id,Name,Title,LastModifiedDate,PhotoUrl"/>
    </apex:remoteObjects>
 
    <body>
      <!-- REQUIRED SLDS WRAPPER -->
      <div class="slds-scope">
        <!-- MASTHEAD -->
        <p class="slds-text-heading--label slds-m-bottom--small">Salesforce Lightning Design System </p>
        <!-- / MASTHEAD -->
        <!-- PAGE HEADER -->
        <div class="slds-page-header">
          <!-- LAYOUT GRID -->
          <div class="slds-grid">
            <!-- GRID COL -->
            <div class="slds-col slds-has-flexi-truncate">
              <!-- HEADING AREA -->
              <!-- MEDIA OBJECT = FIGURE + BODY -->
              <div class="slds-media slds-no-space slds-grow">
                <div class="slds-media__figure">
                  <svg aria-hidden="true" class="slds-icon slds-icon-standard-contact">
                    <use xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/standard-sprite/svg/symbols.svg#contact')}"></use>
                  </svg>
                </div>
                <div class="slds-media__body">
                  <p class="slds-text-title--caps slds-line-height--reset">Contacts</p>
                  <h1 class="slds-page-header__title slds-m-right--small slds-align-middle slds-truncate" title="My Contacts">顧客リスト</h1>
                </div>
              </div>
              <!-- / MEDIA OBJECT -->
              <!-- /HEADING AREA -->
            </div>
            <!-- ACTION BUTTONS -->
            <div class="slds-col slds-no-flex slds-grid slds-align-top">
              <div class="slds-button-group" role="group">
                <button class="slds-button slds-button--neutral">Add Contact </button>
                <button class="slds-button slds-button--neutral">More </button>
              </div>
            </div>
            <!-- / ACTION BUTTONS -->
          </div>
          <!-- / LAYOUT GRID -->
        </div>
        <!-- / PAGE HEADER -->
        <!-- PRIMARY CONTENT WRAPPER -->
        <div class="myapp slds-p-horizontal--medium">
          <ul id="contact-list" class="slds-has-dividers--bottom-space"></ul>
        </div>
        <!-- / PRIMARY CONTENT WRAPPER -->
 
        <!-- FOOTER -->
        <footer role="contentinfo" class="slds-p-around--large">
          <!-- LAYOUT GRID -->
          <div class="slds-grid slds-grid--align-spread">
            <p class="slds-col">Salesforce Lightning Design System Example</p>
            <p class="slds-col">© Your Name Here</p>
          </div>
          <!-- / LAYOUT GRID -->
        </footer>
        <!-- / FOOTER -->
      </div>
      <!-- / REQUIRED SLDS WRAPPER -->
 
 
<!-- JAVASCRIPT -->
<script>
  (function() {
    'use strict';
    var contact = new SObjectModel.Contact();
    var contactList = document.getElementById('contact-list');
 
function createTile (record) {
  return [
    '<li class="slds-item">',
      '<div class="slds-tile slds-media">',
        '<div class="slds-media__figure">',
          '<img class="slds-avatar slds-avatar--medium" src="', record.get('PhotoUrl'), '" alt="" />',
        '</div>',
        '<div class="slds-media__body">',
          '<h3 class="slds-truncate" title="', record.get('Name'), '"><a href="javascript:void(0);">', record.get('Name') ,'</a></h3>',
          '<div class="slds-tile__detail slds-text-body--small">',
            '<p class="slds-truncate">', record.get('Title') ,'</p>',
          '</div>',
        '</div>',
      '</div>',
    '</li>'
  ].join('');
}
 
    contact.retrieve(
      { orderby: [{ LastModifiedDate: 'DESC' }], limit: 10 },
      function(error, records) {
        if (error) {
          alert(error.message);
        } else {
          contactList.innerHTML = records.map(createTile).join('');
        }
      }
    );
  })();
 
</script>
<!-- / JAVASCRIPT -->
    </body>
  </html>
</apex:page>
簡単な解説です。
・ Lightning Design SystemのSVGアイコン使用宣言
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
・ Lightning Design Systemのスタイル、アセットをVisualforceページにインポート
<apex:slds />
・ 「Contact」へアクセスし、javascriptで呼び出 し
<apex:remoteObjectModel name="Contact" fields="Id,Name,Title,LastModifiedDate,PhotoUrl"/>
・ Lightning Design Systemの適用範囲
<div class="slds-scope">...</div>
	 
navigateToURLによるページ画面に遷移する例 は以下です。
//Component: LightningNavigate
<aura:component implements="force:appHostable">
    <div id="aura-page">
        <div class="container">
            <ui:button label="gotoURL" press="{!c.gotoURL}" />
        </div>
        <div class="container">
            <ui:button label="navigate" press="{!c.navigate}" />
        </div>
    </div>
</aura:component>
//Controller
({
    gotoURL : function(component, event, helper) {
        helper.gotoURL(component);
    },
    navigate : function(component, event, helper) {
        helper.navigate(component);
    }
})
//Helper
({
    gotoURL : function (component, event) {
        var urlEvent = $A.get("e.force:navigateToURL");
        urlEvent.setParams({
          "url": "/006/o"
        });
        urlEvent.fire();
    },
    navigate : function(component,event) {
        var address = '/Salesforce.com+Inc/@37.793779,-122.39448,17z/';
        var urlEvent = $A.get("e.force:navigateToURL");
        urlEvent.setParams({
          "url": 'https://www.google.com/maps/place/' + address
        });
        urlEvent.fire();
    }
})
//App
<aura:application >
    <c:LightningNavigate />
</aura:application>
	1.Lightning Component作成
quickcontact.cmp
<aura:component controller="QuickContactController" implements="flexipage:availableForAllPageTypes,force:hasRecordId,force:lightningQuickAction">
    <aura:attribute name="account" type="Account" />
    <aura:attribute name="newContact" type="Contact"
        default="{ 'sobjectType': 'Contact' }" /> <!-- default to empty record -->
    <aura:attribute name="hasErrors" type="Boolean"
        description="Indicate if there were failures when validating the contact." />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <!-- Display a header with details about the account -->
    <div class="slds-page-header" role="banner">
        <p class="slds-text-heading--label">{!v.account.Name}</p>
        <h1 class="slds-page-header__title slds-m-right--small
            slds-truncate slds-align-left">Create New Contact</h1>
    </div>
    <!-- Display form validation errors, if any -->
    <aura:if isTrue="{!v.hasErrors}">
        <div class="recordSaveError">
            <ui:message title="Error" severity="error" closable="true">
                The new contact can't be saved because it's not valid.
                Please review and correct the errors in the form.
            </ui:message>
        </div>
    </aura:if>
    <!-- Display the new contact form -->
    <div class="slds-form--stacked">
        <div class="slds-form-element">
            <label class="slds-form-element__label" 
                for="contactFirstName">First Name: </label>
            <div class="slds-form-element__control">
              <ui:inputText class="slds-input" aura:id="contactFirstName"
                value="{!v.newContact.FirstName}" required="true"/>
            </div>
        </div>
        <div class="slds-form-element">
            <label class="slds-form-element__label" 
                for="contactLastName">Last Name: </label>
            <div class="slds-form-element__control">
              <ui:inputText class="slds-input" aura:id="contactLastName"
                value="{!v.newContact.LastName}" required="true"/>
            </div>
        </div>
        <div class="slds-form-element">
            <label class="slds-form-element__label" for="contactTitle">Title: </label>
            <div class="slds-form-element__control">
              <ui:inputText class="slds-input" aura:id="contactTitle"
                value="{!v.newContact.Title}" />
            </div>
        </div>
        <div class="slds-form-element">
            <label class="slds-form-element__label" 
                for="contactPhone">Phone Number: </label>
            <div class="slds-form-element__control">
              <ui:inputPhone class="slds-input" aura:id="contactPhone"
                value="{!v.newContact.Phone}" required="true"/>
            </div>
        </div>
        <div class="slds-form-element">
            <label class="slds-form-element__label" for="contactEmail">Email: </label>
            <div class="slds-form-element__control">
              <ui:inputEmail class="slds-input" aura:id="contactEmail"
                value="{!v.newContact.Email}" />
            </div>
        </div>
        <div class="slds-form-element">
            <ui:button label="Cancel" press="{!c.handleCancel}"
                class="slds-button slds-button--neutral" />
            <ui:button label="Save Contact" press="{!c.handleSaveContact}"
                class="slds-button slds-button--brand" />
        </div>
    </div>
</aura:component>
2.Lightning Controller作成
quickcontactController.js
({
    doInit : function(component, event, helper) {
        // Prepare the action to load account record
        var action = component.get("c.getAccount");
        action.setParams({"accountId": component.get("v.recordId")});
        // Configure response handler
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(component.isValid() && state === "SUCCESS") {
                component.set("v.account", response.getReturnValue());
            } else {
                console.log('Problem getting account, response state: ' + state);
            }
        });
        $A.enqueueAction(action);
    },
    handleSaveContact: function(component, event, helper) {
        if(helper.validateContactForm(component)) {
            component.set("v.hasErrors", false);
            // Prepare the action to create the new contact
            var saveContactAction = component.get("c.saveContactWithAccount");
            saveContactAction.setParams({
                "contact": component.get("v.newContact"),
                "accountId": component.get("v.recordId")
            });
            // Configure the response handler for the action
            saveContactAction.setCallback(this, function(response) {
                var state = response.getState();
                if(component.isValid() && state === "SUCCESS") {
                    // Prepare a toast UI message
                    var resultsToast = $A.get("e.force:showToast");
                    resultsToast.setParams({
                        "title": "Contact Saved",
                        "message": "The new contact was created."
                    });
                    // Update the UI: close panel, show toast, refresh account page
                    $A.get("e.force:closeQuickAction").fire();
                    resultsToast.fire();
                    $A.get("e.force:refreshView").fire();
                }
                else if (state === "ERROR") {
                    console.log('Problem saving contact, response state: ' + state);
                }
                else {
                    console.log('Unknown problem, response state: ' + state);
                }
            });
            // Send the request to create the new contact
            $A.enqueueAction(saveContactAction);
        }
        else {
            // New contact form failed validation, show a message to review errors
            component.set("v.hasErrors", true);
        }
    },
	handleCancel: function(component, event, helper) {
	    $A.get("e.force:closeQuickAction").fire();
    }
})
3.Lightning Helper作成
quickcontactHelper.js
({
	validateContactForm: function(component) {
        var validContact = true;
        // First and Last Name are required
        var firstNameField = component.find("contactFirstName");
        if($A.util.isEmpty(firstNameField.get("v.value"))) {
            validContact = false;
            firstNameField.set("v.errors", [{message:"First name can't be blank"}]);
        }
        else {
            firstNameField.set("v.errors", null);
        }
        var lastNameField = component.find("contactLastName");
        if($A.util.isEmpty(lastNameField.get("v.value"))) {
            validContact = false;
            lastNameField.set("v.errors", [{message:"Last name can't be blank"}]);
        }
        else {
            lastNameField.set("v.errors", null);
        }
        // Verify we have an account to attach it to
        var account = component.get("v.account");
        if($A.util.isEmpty(account)) {
            validContact = false;
            console.log("Quick action context doesn't have a valid account.");
        }
        // TODO: (Maybe) Validate email and phone number
        return(validContact);
	}
})
4.取引先でアクション追加
オブジェクト名 : 取引先
アクション種別 : Lightning コンポーネント
Lightning コンポーネント : c. quickcontact
高さ : 250ピクセル
表示ラベル : Quick Contact
名前 : Quick_Contact
5.取引先のページレイアウトにLightningアクションを追加
6.Lightning画面にて取引先の詳細画面で、「Quick Contact」アクション押下する。
SalesforceのLightning コンポーネント作成について共有します。
1.開発コンソル開く
設定 > 開発コンソル リンク押下
2. Lightning コンポーネント 作成
開発コンソル画面にて、
メニュー > File > New > Lightning Component
名前 : helloWorld
<aura:component >
	<p>helloWorld</p>
</aura:component>
2.Lightning Application作成
開発コンソル画面にて、
メニュー > File > New > Ligntning Applicaion
名前 : harnessApp
<aura:application >
	<c:helloWorld/>
</aura:application>
Previewボタン押下する。
以下のエラーメッセージが表示される。
Lightning コンポーネントには [私のドメイン] が必要です。詳細は、組織のシステム管理者にお問い合わせください。
Salesforceの組織にて、私のドメイン登録する。
testdaeheuitest-test11-dev-ed.my.salesforce.com
ドメイン登録して、使えるまで数分かかる。
ユーザにリリースすると、使えるようにんります。
Previewボタンを押下すると。以下のように表示されます。
helloWorld
	Salesforceのバッチスケジュールについて共有します。
1.バッチサンプル
global with sharing class Batch_sample implements Database.Batchable<sObject>
{
  private String query;
  
  //コンストラクタ
  global Batch_sample(String q){
  	system.debug('query ---:'+query);
      query = q;
  }
  
  //データ取得
  global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator(query);
  }
  
  //開始
  global void execute(Database.BatchableContext BC, List<sObject> scope){
  
      system.debug('scope.size() ---'+scope.size());//バッチの処理を記述
      executeLogic(scope);
      
  }
  
  //完了
  global void finish(Database.BatchableContext BC)
  {
  	
      //完了後の処理があれば
      String jobName = 'Batch_sample';
      
		CronTrigger ct = getCronTrigger1(jobName);
		if (ct != null) {
			System.abortJob(ct.Id);
		}
      Datetime dt = Datetime.now().addMinutes(2);
      ID pid = System.schedule(jobName, dt.format('0 mm HH dd MM ? yyyy'), new Schedule_sample());
  
  }
  
  public virtual void executeLogic(List<sObject> listSObj){
  	
  	List<Account> accs = new List<Account>();
  	List<customObject__c> customs = new List<customObject__c>();
  	for(sObject sObj : listSobj){
  		Account acc = new Account();
  		acc.Id = String.valueOf(sObj.get('sfid__c'));
  		acc.Dummy__c = Boolean.valueOf(sObj.get('Dummy__c'));
  		accs.add(acc);
  		customObject__c custom = new customObject__c();
  		custom.Id = String.valueOf(sObj.get('Id'));
  		custom.IsProcessed__c = true;
  		customs.add(custom);
  	}
  	
  	try {
  		if(accs.size() > 0){
  			system.debug('executeLogic --- accs.size() --- : '+accs.size());
  			update accs;
  		}
  		if(customs.size() > 0){
  			system.debug('executeLogic --- customs.size() --- : '+customs.size());
  			update customs;
  		}
  	} catch (Exception e) {
  		System.debug(e.getMessage());
  	}
  	
  }
	public static CronTrigger getCronTrigger1(String jobName) {
		List<CronTrigger> result = [
			select		Id
			from		CronTrigger
			where		CronJobDetail.JobType = '7'					// JobType(7) = Scheduled Apex
			and			CronJobDetail.Name =: jobName
			limit		1
		];
		return (result.isEmpty())? null: result[0];
	}
}
2.バッチスケジュールサンプル
global class Schedule_sample implements Schedulable {
  global void execute(SchedulableContext ctx) {
      String soql = 'SELECT Id, SfId__c, Dummy__c, IsProcessed__c FROM customObject__c Where IsProcessed__c = false Order By Id Limit 300';
      Batch_sample b = new Batch_sample(soql);
      Database.executeBatch(b, 200);
  }
}
3.バッチテストクラス
@isTest (SeeAllData = false)
private class TestBatch_sample {
	// 同期バッチテスト1 (スケジュールクラステスト)
	static testMethod void myUnitTest1() {
		List<Account> accs = new List<Account>();
		for(Integer i =1; i<=100; i++ ){
			Account acc = new Account();
			acc.Name = 'test' + String.ValueOf(i);
			accs.add(acc);
		}
		insert accs;
		List<Account> accList = new List<Account>();
		accList = [SELECT Id From Account];		
		List<customObject__c> customs = new List<customObject__c>();
		for(Integer i =0; i<100; i++ ){
			customObject__c custom = new customObject__c();
			custom.SfId__c = String.ValueOf(accList.get(i).Id);
			custom.Dummy__c = true;
			custom.IsProcessed__c = false;
			customs.add(custom);
		}
		insert customs;
		
		test.startTest();
		ID pid = System.schedule('TestBatch_sample', Datetime.now().addMinutes(2).format('0 mm HH dd MM ? yyyy'), new Schedule_sample());
		test.stopTest();
		
	}
    
}
	SalesforceのSOQL比較演算子について共有します。
SELECT Name FROM Account
WHERE BillingState IN ('California', 'New York')
SELECT AccountId, FirstName, lastname FROM Contact WHERE lastname LIKE 'appl%'
SELECT Name FROM Account
WHERE BillingState NOT IN ('California', 'New York')
SELECT Id 
FROM Account 
WHERE Id NOT IN
  (
    SELECT AccountId
    FROM Opportunity
    WHERE IsClosed = false
  )
SELECT Id, Name FROM Account WHERE Parent.Name = 'myaccount'
Account A = new Account(Name='xxx');
insert A;
Account B;
// A simple bind
B = [SELECT Id FROM Account WHERE Id = :A.Id];
// A bind with arithmetic
B = [SELECT Id FROM Account 
     WHERE Name = :('x' + 'xx')];
String s = 'XXX';
// A bind with expressions
B = [SELECT Id FROM Account 
     WHERE Name = :'XXXX'.substring(0,3)];
// A bind with an expression that is itself a query result
B = [SELECT Id FROM Account
     WHERE Name = :[SELECT Name FROM Account
                    WHERE Id = :A.Id].Name];
Contact C = new Contact(LastName='xxx', AccountId=A.Id);
insert new Contact[]{C, new Contact(LastName='yyy', 
                                    accountId=A.id)};
// Binds in both the parent and aggregate queries
B = [SELECT Id, (SELECT Id FROM Contacts
                 WHERE Id = :C.Id)
     FROM Account
     WHERE Id = :A.Id];
// One contact returned
Contact D = B.Contacts;
// A limit bind
Integer i = 1;
B = [SELECT Id FROM Account LIMIT :i];
// An OFFSET bind
Integer offsetVal = 10;
List<Account> offsetList = [SELECT Id FROM Account OFFSET :offsetVal];
// An IN-bind with an Id list. Note that a list of sObjects
// can also be used--the Ids of the objects are used for 
// the bind
Contact[] cc = [SELECT Id FROM Contact LIMIT 2];
Task[] tt = [SELECT Id FROM Task WHERE WhoId IN :cc];
// An IN-bind with a String list
String[] ss = new String[]{'a', 'b'};
Account[] aa = [SELECT Id FROM Account 
                WHERE AccountNumber IN :ss];
// A SOSL query with binds in all possible clauses
String myString1 = 'aaa';
String myString2 = 'bbb';
Integer myInt3 = 11;
String myString4 = 'ccc';
Integer myInt5 = 22;
List<List<SObject>> searchList = [FIND :myString1 IN ALL FIELDS 
                                  RETURNING 
                                     Account (Id, Name WHERE Name LIKE :myString2
                                              LIMIT :myInt3), 
                                     Contact, 
                                     Opportunity, 
                                     Lead 
                                  WITH DIVISION =:myString4 
                                  LIMIT :myInt5];
List keyAccounts;
「WHERE ID IN :keyAccounts」
SalesforceでVisualForce、Apex で現在のユーザ情報取得方法を共有します。
1. VisualForceで現在のユーザ情報取得方法
<apex:page>
  <h1>Congratulations</h1>
   This is your new Apex Page
   <p>The current company name for this 
      user is: {!$User.CompanyName}</p>
   <p>Is the user active?  
      {!$User.isActive}</p>
</apex:page>
2. Apex で現在のユーザ情報取得方法
String result = UserInfo.getLocale();
System.assertEquals('en_US', result);
	Salesforceでよく使われているStandardControllerとStandardSetController使い分けについて共有する。
1.カスタムボタンでの使い分け
表示ボタン : StandardController
リストビューボタン : StandardSetController
※表示ボタン : 詳細画面に配置して使用
※リストビューボタン : 関連リストのメニューに配置して使用
2.Visualforceとコントローラでの使い分け
StandardController の場合
・Visualforce page
<apex:page standardController="Account" extensions="myControllerExtension">
    {!greeting} <p/>
    <apex:form>
        <apex:inputField value="{!account.name}"/> <p/>
        <apex:commandButton value="Save" action="{!save}"/>
    </apex:form>
</apex:page>
・コントローラ
public class myControllerExtension {
    private final Account acct;
    
    // The extension constructor initializes the private member
    // variable acct by using the getRecord method from the standard
    // controller.
    public myControllerExtension(ApexPages.StandardController stdController) {
        this.acct = (Account)stdController.getRecord();
    }
    public String getGreeting() {
        return 'Hello ' + acct.name + ' (' + acct.id + ')';
    }
}
StandardSetController
・Visualforce Page
<apex:page controller="opportunityList2Con">
    <apex:pageBlock>
        <apex:pageBlockTable value="{!opportunities}" var="o">
            <apex:column value="{!o.Name}"/>
            <apex:column value="{!o.CloseDate}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>
・コントローラ
public class opportunityList2Con {
    // ApexPages.StandardSetController must be instantiated
    // for standard list controllers
    public ApexPages.StandardSetController setCon {
        get {
            if(setCon == null) {
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                    [SELECT Name, CloseDate FROM Opportunity]));
            }
            return setCon;
        }
        set;
    }
    // Initialize setCon and return a list of records
    public List<Opportunity> getOpportunities() {
        return (List<Opportunity>) setCon.getRecords();
    }
}
	SalesforceのClassicでOnClick JavaScriptボタンをLightning Experienceに移行する際にその方法の一つを共有します。
1.詳細ボタンの場合
Classic:
window.open(“/apex/Test_VF?id=”+ ids, “_blank”);
Lightning Experience:
window.location.href = '/apex/Test_VF?id={!ids}';
2.リストビューボタンの場合
Classic:
var ids = {!GETRECORDIDS($ObjectType.Test__c)};
if (ids.length === 0) {
    alert('None');
} else {
    var test_url = '{!URLFOR("/apex/Test_VF?id=")}' ;
    window.open(test_url + ids, 'Test');
} 
Lightning Experience:
<script type="text/javascript">
    var __sfdcSessionId = '{!GETSESSIONID()}';
</script>
<script src="../../soap/ajax/44.0/connection.js" type="text/javascript"></script>
<script src="../../soap/ajax/44.0/apex.js" type="text/javascript"></script>
<script type="text/javascript">
    var ids = "<apex:repeat value="{!selected}" var="obj">{!obj.Id},</apex:repeat>".slice(0,-1).split(',');
    if (ids[0] == "") { 
        alert('None');
        history.back();
    } else { 
        window.location.href = '/apex/Test_VF?id='+ids;
    }
</script>