In this blog you will find the source code (below) to “let NAV speak.” You would have a wide range of possibilities to use this simple Add-in and enlarge this project.
If you want to know more about Client Add-ins you can refer to this MSDN link:
Extending the RoleTailored Client Using Control Add-ins and Microsoft Dynamics NAV 2009 SP1
This simple Client Add-In is based on System.Speech namespace:
Microsoft.Speech.Synthesis Namespace
Step by step creation of the NSpeech Add-In
(Remember the ‘DodgeBall’ rules: Develop, Sign, Place, Register and Develop)
A. Create a New Class Project
B. Create a Strong Name Key (SNK)
C. Add References to the Project
D. Develop your NSpeech Project
(You can simply copy and paste this code into your Class project.)
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
//Add a reference to the Add-in API (see the solution explorer) and all relevant references
//Use all relevant references
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Dynamics.Framework.UI.Extensibility;
using Microsoft.Dynamics.Framework.UI.Extensibility.WinForms;
//this is to let this add-in speech
//http://msdn.microsoft.com/en-us/library/dd146744(v=office.13).aspx
using System.Speech;
using System.Speech.Synthesis;
namespace NSpeech
{
//Develop the control add-in class.
//Assign a name to the control add-in (MyCompany.MyProduct.MyAddIn)
[ControlAddInExport("Cronus.DynamicsNAV.NSpeech")]
[Description("Let this Add-in Speak")]
//Select a base class as a starting point.
//Select interfaces to implement features, such as data binding or event handling.
public class Class1 : StringControlAddInBase
//Implement control creation
protected override Control CreateControl()
//Create a brand new TextBox
TextBox control = new TextBox();
//Define TextBox size
control.MinimumSize = new Size(50, 0);
control.MaximumSize = new Size(500, Int32.MaxValue);
//Add a DoubleClick event for the TextBox
control.DoubleClick += new EventHandler(control_DoubleClick);
return control;
}
//Define a voice synth
private SpeechSynthesizer synth;
private void control_DoubleClick(object sender, EventArgs e)
//create a new speech synth and set default audio device
synth = new SpeechSynthesizer();
synth.SetOutputToDefaultAudioDevice();
//Pass TextBox content in a string variable
string data = this.Control.Text;
//... and let NAV speak it!
synth.SpeakAsync(data);
E. Build the NSpeech.dll
F. Place DLL into Add-in folder
(typically the Add-ins folder is here: C:\Program Files\Microsoft Dynamics NAV\60\RoleTailored Client\Add-ins)
G. Determine the PKT (Public Key Token) of NSpeech
Sn –T “C:\TMP\NSpeech\NSpeech\bin\Debug\NSpeech.dll” In the following example, 250f71f35a467631 is the PKT (Public Key Token) needed to register the Add-in into NAV. (You will have another value.)
Sn –T “C:\TMP\NSpeech\NSpeech\bin\Debug\NSpeech.dll”
In the following example, 250f71f35a467631 is the PKT (Public Key Token) needed to register the Add-in into NAV. (You will have another value.)
H. Register the NSpeech dll
How to Use This Add-in
As an example, you can just let NAV speak the content of the field “Name” in Customer Card page (Page 21).
Now…you are ready to let NAV speak the Customer Name from the customer card by simply double clicking on on the Name!
This simple Client Add-in project may be used in, e.g.
This simple Client Add-in project may be enlarged, e.g.
These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.
Best Regards,
Duilio Tacconi (dtacconi)
Microsoft Dynamics Italy
Microsoft Customer Service and Support (CSS) EMEA
In the RoleTailored client, the Search feature finds only pages and reports that are accessible from the navigation pane, which includes the Home button, Activity buttons, and Departments. So if you want to make a page or report available from search, then add it to the Home button, an Activity button, or Departments.
For information about adding pages and reports to the Home Button and Activity buttons, see Home Button Overview and Creating Activity Buttons for the Navigation Pane in the MSDN library.
To add a page or report to Departments, you add it to the MenuSuite object that is used by the RoleTailored client. For more information, see How to: Create and Modify a MenuSuite Object in the MSDN Library.
In several places in NAV 2009 SP1, it has been used ListPlus pages in order to display two-dimension matrix. Those ListPlus Pages may be customized in order to be arranged as FactBoxes directly inside a main page (Document, Worksheet, etc.).
The main concept of those kind of two-dimensional matrix pages is that they have a Page Part with a List that is updated every time a value is changed in the analysis parameter bounded to fields and/or variables that belongs directly to the ListPlus.
This post will provide the basics on how to integrate the Item Availability by Location directly as FactBoxes instead of being called from RTC actions. The same concept may be applied to Item Availability by Period and Item Availability by Variant (and/or all of them together). In the example, the Planning Worksheet page is used as the main page.
The next step will guide you through the modifications that need to be performed in order to arrange Page 492 “Item Availability By Location” as a FactBox. (In the standard Cronus this is called from an action present in the Related Information action group.)
GRBool (for GrossRequirement StyleExpr)
SRBool (for ScheduledReceipt StyleExpr)
PORBool (for PlannedOrderReceipt StyleExpr)
PABBool (for ProjAvailBalance StyleExpr)
InvBool (for Item.Inventory StyleExpr)
QPOBool (for Item."Qty. on Purch. Order" StyleExpr)
QSOBool (for Item.”Qty. on Sales Order” StyleExpr)
TOSQBool (for Item.”Trans. Ord. Shipment (Qty.)” StyleExpr)
QTBool (for Item.”Qty. in Transit” StyleExpr)
TORQBool (for Item.”Trans. Ord. Receipt(Qty.)” StyleExpr)
EIBool (for ExpectedInventory StyleExpr)
AvInvBool (for QtyAvailable StyleExpr)
SRQBool (for Item.”Scheduled Receipt(Qty.)” StyleExpr)
SNQBool (for Item.”Scheduled Need (Qty.)” StyleExpr)
PORLBool (for PlannedOrderReleases StyleExpr)
NetChBool (for Item.”Net Change” StyleExpr)
GRBool := GrossRequirement <> 0;
SrBool := ScheduledReceipt <> 0;
PORBool := PlannedOrderReceipt <> 0;
PABBool := ProjAvailBalance <> 0;
InvBool := Item.Inventory <> 0;
QPOBool := Item."Qty. on Purch. Order" <> 0;
QSOBool := Item."Qty. on Sales Order" <> 0;
TOSQBool := Item."Trans. Ord. Shipment (Qty.)" <> 0;
QTBool := Item."Qty. in Transit" <> 0;
TORQBool := Item."Trans. Ord. Receipt (Qty.)" <> 0;
EIBool := ExpectedInventory <> 0;
AvInvBool := QtyAvailable <> 0;
SRQBool := Item."Scheduled Receipt (Qty.)" <> 0;
SNQBool := Item."Scheduled Need (Qty.)" <> 0;
PORLBool := PlannedOrderReleases <> 0 ;
NetChBool := Item."Net Change" <> 0;
…
ExpectedInventory := AvailabilityMgt.ExpectedQtyOnHand(Item,TRUE,0,QtyAvailable,31129999D);
END;
InitBoolean; //Add this line
Type: Group, SubType: Group, Caption: Availability Options
Type: Field, Caption: View by, SourceExpr: ItemPeriodLength, Style: Unfavorable, StyleExpr: TRUE
Type: Field, Caption: View as, SourceExpr: AmountType, Style: Unfavorable, StyleExpr: TRUE
Type: Field, Caption: Period, SourceExpr: DescDateFilter, Editable: FALSE
..
IF ItemForIALL.GET(ItemNo) THEN BEGIN
FindPeriod('',ItemForIALL);
CurrPage.IALL.FORM.Set(ItemForIALL,ItemPeriodLength,AmountType);
FindPeriod(SearchText : Code[10];VAR ItemRec : Record Item)
On the FindPeriod function, add a local variable:
And add this code to the FindPeriod function:
IF ItemRec.GETFILTER("Date Filter") <> '' THEN BEGIN
Calendar.SETFILTER("Period Start",ItemRec.GETFILTER("Date Filter"));
IF NOT PeriodFormMgt.FindDate('+',Calendar,ItemPeriodLength) THEN
PeriodFormMgt.FindDate('+',Calendar,ItemPeriodLength::Day);
Calendar.SETRANGE("Period Start");
PeriodFormMgt.FindDate(SearchText,Calendar,ItemPeriodLength);
IF AmountType = AmountType::"Net Change" THEN BEGIN
ItemRec.SETRANGE("Date Filter",Calendar."Period Start",Calendar."Period End");
IF ItemRec.GETRANGEMIN("Date Filter") = ItemRec.GETRANGEMAX("Date Filter") THEN
ItemRec.SETRANGE("Date Filter",ItemRec.GETRANGEMIN("Date Filter"));
END ELSE
ItemRec.SETRANGE("Date Filter",0D,Calendar."Period End");
DescDateFilter := ItemRec.GETFILTER("Date Filter");
PeriodItemPeriodLengthOnPush
YearItemPeriodLengthOnPush
QuarterItemPeriodLengthOnPush
MonthItemPeriodLengthOnPush
WeekItemPeriodLengthOnPush
DayItemPeriodLengthOnPush
NetChangeAmountTypeOnPush
BalanceatDateAmountTypeOnPush
DayItemPeriodLengthOnValidate
WeekItemPeriodLengthOnValidate
MonthItemPeriodLengthOnValidat
QuarterItemPeriodLengthOnValid
YearItemPeriodLengthOnValidate
PeriodItemPeriodLengthOnValida
NetChangeAmountTypeOnValidate
BalanceatDateAmountTypeOnValid
...
ERROR('');
ReqJnlManagement.OpenJnl(CurrentWkshBatchName,Rec);
FindPeriod('',ItemForIALL); //Add this line
And in the OnAfterGetRecord(); trigger, in the bottom, this code
PlanningWarningLevel1OnFormat;
ItemNo := "No."; //Add this line
UpdateSubForm; //Add this line
Type: ActionGroup, Caption: Availability
Type: Action, Caption: Previous Period, Image: PreviousRecord, Promoted: Yes, PromotedCategory: Category4, ShortCutKey: CTRL+Q
Type: Action, Caption: Next Period, Image: NextRecord, Promoted: Yes, PromotedCategory: Category4, ShortCutKey: CTRL+W
Right now you have completed all the steps necessary to create a FactBox for Item Availability by Location.
Attached you will find a .txt file with the example above, extended to Item availability by Location, by Period and by Variant too. Captions have been added for ENU and ITA.