TypeSafe Enums + readResolve + New Types
I have the following code:
public final class Type implements java.io.Serializable {
public static final Type TYPEA= new Type ("TYPEA");
public static final Type TYPEB= new Type ("TYPEB");
public static final Type TYPEC= new Type ("TYPEC");
public static final Type TYPED= new Type ("TYPED");
private String type;
public Type (String type) {
this.type = type;
public String toString() {
return this.type;
private static int nextOrdinal = 0;
private final int ordinal = nextOrdinal++;
private static final Type [] VALUES = { TYPEA, TYPEB, TYPEC, TYPED};
Object readResolve() throws ObjectStreamException {
return VALUES[ordinal];
}My problem is that I want the user to be able to add a new type for example lets say TYPEF. how would I go about doing this and also make it work with serialiazable?
you can overcome the and .equals() failing with a very minor amount of code. Basically you need a set of all possible typesafe values.
Additionally you need to implement readResolve to prevent serialization from cloning.
Finally - it's just never a good idea to use == for equality comparison. It should only be used for identity comparison (and even then most of the time you should have equals perform the identity comparison).
private static final Stooge[] ALL = new Stooge{Moe, Larry, Curly};
//see java.io.Serializable for details
protected Object readResolve() throws ObjectStreamException {
return getTypeFor(this.name);
//you usually need this for retrieval from persistent storage
public static Stooge getTypeFor(String name){
Stooge result = null;
for(int i = 0; i < ALL.length; i++){
if(ALL.name.equals(name)){
result = ALL[i];
break;
return result;
Similar Messages
-
I have a class, one of it's attributes is a typesafe enum:
public class Title {
TitleType type;
int titleId;
String titleName;
public TitleType getTitleType() {
return this.type;
public class TitleType {
private final String name;
private final int typeId;
private TitleType(String name, int typeId) {
this.name = name;
this.typeId = typeId;
public String toString() {
return this.name;
public int toInt() {
return this.typeId;
public static final TitleType MAIN_TITLE = new TitleType("MAIN", 1);
public static final TitleType SUB_TITLE = new TitleType("SUB", 2);
}My table is:
TITLES (
title_id numeric,
title_type varchar,
title_name varchar)
How do I map the TitleType class/attributes' String value to the column title_type in titles?
For a title with TitleType TitleType.MAIN_TITLE my table should look like:
title_id title_type title_name
1 MAIN "The Guiness book of records"Regards,
AnthonyThanks Doug,
I created the AfterLoad class and unmapped the field.
For some reason though all the titles loaded from the table are coming through as just "MAIN" TitleType.
Heres the AfterLoad class:
public class AfterLoad {
public static void afterLoadTitle(Descriptor descriptor) {
ObjectTypeMapping otm = new ObjectTypeMapping();
otm.setAttributeName("titleType");
otm.setFieldName("TITLE_TYPE");
otm.addConversionValue(TitleType.MAIN_TITLE.toString(), TitleType.MAIN_TITLE);
otm.addConversionValue(TitleType.SUB_TITLE.toString(), TitleType.SUB_TITLE);
otm.addConversionValue(TitleType.TRANSLATED_TITLE.toString(), TitleType.TRANSLATED_TITLE);
otm.setDescriptor(descriptor);
descriptor.addMapping(otm);
}Any idea why?
Regards,
Anthony -
Hello,
I know that this topic is already cleared that not possible to extend typesafe enum.
But I don't have any other solution than doing this.
Here is my problem.
I have 2 package.
- package generated
- package design
The purpose of the programs is to wrapping package generated in package design, that the user of this program should not use even the smallest part of the package generated.
package generated contains class A, B, and enum Type
Here are the declarations:
File: generated/Type.java
package generated;
package generated;
enum Type
read, write, readwrite;
}File: generated/B.java
package generated;
public class B
int num;
void setNum(int num){this.num = num;}
int getNum(){ return num;}
}File: generated/A.java
package generated;
public Class A
int num;
Type type;
B b;
void setNum(int num){this.num = num;}
int getNum(){ return num;}
void setType(Type type){this.type = type;}
Type getType(){ return type;}
void setB(B b){this.b = b;}
B getB(){ return b;}
}Now inside package design:
File: design/B.java
package design;
public class B
extends generated.B
}File: design/A.java
package design;
public Class A
extends generated.A
}Here is the problem:
File: App.java
import design.*;
class App{
public static void main(String args[])
A a = new A();
B b = new B();
a.setB(b);
//This part is not expected, while it's using the type of package generated
//a.setType( generated.Type.write);
}The problem here is by setting the type of class A. While the method setType of design.A is inherited from generated.A, I cannot setting the value of this type without using the Type from the package generated, even when I add a enum of Type in package design, it still doesn't work, while there couldn't be casted from design.Type to generated.Type.
This problem is not arised with setB(), while design.B is the subclass of generated.B, and thus can be casted automatically.
So I have no Idea how can I solve this thing.
As a note, the package generated cannot be changed.
If there are anybody have ever faced the same problem, maybe can share their experience.
Thanks a lot in advance.
Best regards,
HeruHi,
thanks for the reply.
I'm actually making an API of a data source using JAXB to generate Java Code from an XML schema.
This generated package is going to have features added along the time. So the wrapper I make is to assure that the API still work when new functions/features added. If I don't create any Wrapper, my written code (extension of the generated code) would be replaced by the new generated code each time the new features added.
The reason I restrict the user to access the generated package, is because I don't want to confuse the user to access around the generated package and the wrapper package. The purpose of this wrapper is to completely wrapping whole the function of the generated code.
Hopefully my explanation is understandable.. :-)
Do you have any other advice how to accomplish this?
Thanks.
Best regards,
Heru -
I have tranaslated an enum type from C using the "typesafe enum pattern" (see, e.g. Bloch: Effective Java, p.104). I want to OR two of the enum values together. E.g.
Classname.FIRST | Classname.SECOND
but because they are instances of a class and not int values I get an "operator cannot be applied..." error from the compiler. How can I augment/modify the class to make this operation legal and correct?
Many thanks.You would need to associate an integer ordinal with each enum. Josh demonstrates something like this later in the chapter for an enum that implements Comparable. Since you want to work with bitwise values, you'll need to make each successive ordinal a power of two so each enum maps to one bit. It might look something like this: public class MyEnum implements Comparable {
/** ordinal of next enum to be created */
static private int nextOrdinal = 1 ;
/** returns next ordinal to assign */
static private int getNextOrdinal() {
int thisOrd = nextOrdinal ;
nextOrdinal <<= 1 ;
return thisOrd ;
/** face name of this enum */
private final String name ;
/** bitwise ordinal for this enum */
private final int ordinal = getNextOrdinal() ;
private MyEnum(String name) { this.name = name ; }
public String toString() { return name ; }
public int getOrdinal() { return ordinal ; }
public int compareTo(Object o) { return ordinal - ((MyEnum)o).ordinal ; }
static public final MyEnum FIRST = new MyEnum("First") ;
static public final MyEnum SECOND = new MyEnum("Second") ;
static public final MyEnum THIRD = new MyEnum("Third") ;
static public final MyEnum FOURTH = new MyEnum("Fourth") ;
} Then, two enums are "OR'd" together like so: MyEnum.FIRST.getOrdinal() | MyEnum.SECOND.getOrdinal(). -
Hi all,
In the Effective Java Programming Language Guide by: Joshua Bloch, chapter: 5, item: 21, I came across the following:
+Constants maybe added to a typesafe enum class w/o recompiling its clients b/c the public static object reference fields containing the enumeration constants provide a layer of insulation bet. the client and the enum class.+
What does that mean?
The constants themselves are never compiled into clients as they are in the more common int enum pattern and its String variant.
What does that mean?
Can someone please explain the above in more detail or guide me in another doc./article which helps me get the point?
Any help is greatly appreciated.
Edited by: RonitT on Apr 20, 2009 2:53 PMIn any case, that item should be updated now to advise you to use the Enum types introduced in 1.5 instead of rolling yer own. You are right, I'll use that instead - looks like I have an old edition of book!
Anyway. just for me to understand what you mentioned, since the client code sees the value of RANDOM -- like 17 and not 42 -- so let say my client code has the constants 0 thru 10 and now I need to add new constants from 11 to 20, if I'm confident that my client will never need these new constants, I don't need to give them the new code which contains the values 11 thru 20, is that right? That was you were trying to tell me?
Thanks again. -
Typesafe enums with private access - strange or useful?
Given the class listed at the bottom, you'll notice that it's possible to specify a typesafe enum, and restrict that enum to clients in such a way that - and here's the strange part - the constant class is not exported in the api, despite the fact that it's required as an argument to the constructor.
In other words you can legally state:
MyClass myClass = new MyClass(MyClass.PLAIN);but not:
MyClass.Constant constant = MyClass.PLAIN;
MyClass myClass = new MyClass(constant);Anyone else noticed this? (Still coming to terms with the meaning of it).
/k1
Example code:
* Type safety demo
package blah;
* Demo class showing the use of inaccessible constants
public class MyClass {
/** My first constant */
public static final Constant FIRST;
/** My second constant */
public static final Constant SECOND;
/* The instance constant field */
private Constant constant;
/* static initialiser for the constants */
static {
FIRST = new Constant("First");
FANCY = new Constant("Second");
* @param constant The constant spec
public MyClass(Constant constant) {
super();
this.constant = constant;
private static class Constant {
private String name;
* @param name The name of my constant
public Constant(String name) {
this.name = name;
}And indeed outside the package...
package blah.test;
import blah.*;
public class Driver {
* Main method for the sake of demonstration...
public static void main(String[] args) {
Object[] constants = MyClass.VALUES;
for (int i = 0; i < constants.length; i++) {
System.out.println(constants);
MyClass myClass = new MyClass(constants[i]);
System.out.println(myClass);
...then...
* Type safety demo
package blah;
* Demo class showing the use of inaccessible constants
public class MyClass {
/** My first constant */
public static final Constant FIRST = new Constant("First");
/** My second constant */
public static final Constant SECOND = new Constant("Second");
/** An array of the constants */
public static final Constant[] VALUES = { FIRST, SECOND };
/* The instance constant field */
private Constant constant;
* @param constant The constant spec
public MyClass(Object constant) {
super();
if (constant instanceof Constant) {
this.constant = (Constant)constant;
private static class Constant {
private String name;
* @param name The name of my constant
public Constant(String name) {
this.name = name;
* @return The name of the constant
public String toString() {
return name; -
In the interview Joshua Bloch states the the new 1.5 feature "Typesafe enums - Provides all the well-known benefits of the Typesafe Enum pattern"
Does it also provide the pitfalls? The typesafe enum pattern is nice. However, in a multi-classloader environment it can behave unexpectedly. Similar to the Singleton pattern, it is generally best to avoid it in app-server code.
Does the 1.5 implementation essentially compile to the pre-1.5 manual implementation or does it deal with this issue?you can overcome the and .equals() failing with a very minor amount of code. Basically you need a set of all possible typesafe values.
Additionally you need to implement readResolve to prevent serialization from cloning.
Finally - it's just never a good idea to use == for equality comparison. It should only be used for identity comparison (and even then most of the time you should have equals perform the identity comparison).
private static final Stooge[] ALL = new Stooge{Moe, Larry, Curly};
//see java.io.Serializable for details
protected Object readResolve() throws ObjectStreamException {
return getTypeFor(this.name);
//you usually need this for retrieval from persistent storage
public static Stooge getTypeFor(String name){
Stooge result = null;
for(int i = 0; i < ALL.length; i++){
if(ALL.name.equals(name)){
result = ALL[i];
break;
return result; -
PersistenceDelegate for typesafe enum pattern
I've converted my code over from using int constants to the typesafe enum pattern in Effective Java. Unfortunately, the pattern only goes into serialization using Serializable and does not go into how to write a proper PersistenceDelegate that parallels the safety precautions of the Serializable enum. I've tried to do a direct mirroring of the readResolve() method given in the book inside of the intiatiate method of my PersistenceDelegate, but the XMLEncoder keeps rejecting the output and I get an InstantiationException, which shouldn't happen since the method call should not instantiate any new instances since the enums are static.
class PositionBiasModePersistenceDelegate extends PersistenceDelegate {
protected Expression instantiate(Object oldInstance, Encoder out) {
PositionBiasMode mode = (PositionBiasMode) oldInstance;
return new Expression(mode, PositionBiasMode.VALUES, "get", new Object[] {new Integer(PositionBiasMode.VALUES.indexOf(mode))});
public abstract class PositionBiasMode {
private final String name;
private static int nextOrdinal = 0;
private final int ordinal = nextOrdinal++;
/** Creates a new instance of PreferredPositionMode */
private PositionBiasMode(String name) {
this.name = name;
public String toString() {
return name;
public abstract boolean complies(PositionBias pb);
public static final PositionBiasMode IGNORE = new PositionBiasMode("Ignore") {
public boolean complies(PositionBias pb) {
return true;
public static final PositionBiasMode FRONT = new PositionBiasMode("Front") {
public boolean complies(PositionBias pb) {
return pb.hasBias() && pb.getPositionBias() < 0 ? false : true;
public static final PositionBiasMode BACK = new PositionBiasMode("Back") {
public boolean complies(PositionBias pb) {
return pb.hasBias() && pb.getPositionBias() >= 0 ? false : true;
private static final PositionBiasMode[] PRIVATE_VALUES = {IGNORE, FRONT, BACK};
public static final List VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
}Yeah I tried this too. I think the instantiation exception is something to do with it trying to recreate the MyEnum.VALUES List. I don't understand enough about the process to know how to fix that though.
The approach I eventually went for was to add a couple of things to the enum class as follows:
// add to MyEnum class:
public static final PersistenceDelegate PERSISTENCE = new PersistenceDelegate()
protected boolean mutatesTo(Object oldInstance, Object newInstance)
return (MyEnum)oldInstance == (MyEnum)newInstance;
protected Expression instantiate(Object oldInstance, Encoder out)
MyEnum enum = (MyEnum)oldInstance;
return new Expression(enum, new MyEnum.Factory(), "forOrdinal", new Object[]{new Integer(enum.ordinal)});
public static final class Factory
public MyEnum forOrdinal(int ordinal)
return PRIVATE_VALUES[ordinal];
// usage:
XMLEncoder enc = new XMLEncoder(...);
enc.setPersistenceDelegate(MyEnum.class, MyEnum.PERSISTENCE);Not entirely sure it's the ideal approach but maybe it'll work for you. Cheers. -
I do not use J2SE 5.0, and I need to use an enumerator-like construct. My original code was:
// Constants to be used with runnersOnBase
public static final short RUNNER_ON_FIRST = 1;
public static final short RUNNER_ON_SECOND = 2;
public static final short RUNNER_ON_THIRD = 4;Obviously this is not a great practice, so I decided to try typesafe enums, which are explained here: http://java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums
The problem I'm having comes from the fact that, in my program, I can add the integer constants together. Is there a similar way to do that with typesafe enums, and if so, how should the enum class be set up? Thanks a lot. Take care.The problem I'm having comes from the fact that, in
my program, I can add the integer constants together.
Is there a similar way to do that with typesafe
enums, and if so, how should the enum class be set
up? Thanks a lot. Take care.Something like
public class Enum {
private static Map enums;
public static Enum A = new Enum();
public static Enum B = new Enum();
public static Enum C = new Enum();
static {
enums.add( Integer.valueOf( 0 ), A );
enums.add( Integer.valueOf( 0 ), B );
enums.add( Integer.valueOf( 0 ), C );
public static Enum add( Enum a, Enum b ) {
int av = enums.get( a );
int bv = enums.get( b );
Enum value = enums.get( Integer.valueOf( av + bv ) );
// if( value == null ) throw some exception maybe?
return value;
}maybe? -
The predecessor to the "typesafe enum pattern"
In 1998, Michael Bridges published the following on Dr.Dobb's Portal
(http://www.ddj.com/windows/184403569):
class BookAgeLevel
private BookAgeLevel(){}
// Following are all the BookAgeLevel objects
// there will ever be.
final static BookAgeLevel TODDLER = new BookAgeLevel();
final static BookAgeLevel CHILD = new BookAgeLevel();
final static BookAgeLevel TEENAGER = new BookAgeLevel();
final static BookAgeLevel ADULT = new BookAgeLevel();
}In 1999, Nigel Warren and Philip Bishop refers to the exact same pattern as the "typesafe
constant idiom" in their book "Java in Practice" (page 48):
public final class Alienrace
public static final AlienRace BORG = new Alienrace();
public static final AlienRace FERENGI = new Alienrace();
private AlienRace() {}
}In 2000, Joshua Bloch refers to the following code as the "typesafe enum pattern" (http://java.sun.com/developer/Books/shiftintojava/page1.html):
// The typesafe enum pattern
public class Suit {
private final String name;
private Suit(String name) { this.name = name; }
public String toString() { return name; }
public static final Suit CLUBS = new Suit("clubs");
public static final Suit DIAMONDS = new Suit("diamonds");
public static final Suit HEARTS = new Suit("hearts");
public static final Suit SPADES = new Suit("spades");
}sunfun99 wrote:
No point, just interesting. There is no question attached to this.OK - I still have a load of code in both C++ and Java that uses this Pattern ( it ain't broke so I ain't fixing it) and I first started using this in C++ in about 1987 (God 20 years ago). I didn't invent it for myself so it must be older than that. -
Training and event management - create new type of attendee
Hi all,
For training and event management, I have to create a new type of attendee besides sap existing attendee type such as company, contact person, customer, external person and so on.
Via IMG -> Training and event management -> basic settings -> object type modeling enhancement -> object type -> define object types, then how can I define OrgObj Type for new object type I want to create?
Thanks & regards,
WCCS_AHR_61016216 - Cancellations per Attendee , i think there is no standard report for cencelation of business events, type and group.
for cancellations per attendee reports is available in the system.
good luck
Devi -
Importing Through DTW : "Invalid ItemName'M' in Enum 'BO Gender Types
Dear Members,
I am trying to import in a Business Partner,the contact person in which the gender and date of birth is to be imported.?its showing an error named "Invalid Item Name'M' in Enum 'BO Gender Types 65171.
Can anyone help me in this regard to import through template.
Thanks ,
Venkatesh.RHi sudha,
Thanks a lot,one of my issues has been solved,can you tell me how to import similarly for date of birth.
Regards,
Venkatesh.R -
Definition of a new type of invoice for Evaluated Receipt Settlemen (ERS)
Hello,
I need to define a new type of invoice for Evaluated Receipt Settlemen (ERS). Is it possible? What should i do to configure the system?
Thanks in advance,
Luis Álvarez.Hi,
ERS is used for invoice plan & invoicing plan for leasing agreements like, aim to considerably reduce the manual data entry effort in the purchasing and invoice verification (A/P) department.
The invoicing plan enables you to schedule the desired dates for the creation of invoices relating to the planned procurement of materials or services independently of the actual receipt of the goods or actual performance of the services. It list the dates on which you wish to create and then pay the invoices.
The steps are,
1.XK02: In Purchasing Data tick the check box of AutoEvalGRSetmt Del,
2.ME12: Should not select No ERS check box,
3.ME21N: Create PO,
4.MIGO: Receive Goods,
5.MRRL: Evaluated Receipt Settlement
Link may be useful.
http://help.sap.com/saphelp_srm30/helpdata/en/fb/8dec38574c2661e10000000a114084/content.htm -
Add a new type of object links (transaction CV02N) - by material group .
Hi experts .
How can I create an additional screen for new tab by material group
in DMS System ?
I have a requirement : 1. Add a new type of object links in transaction CV02N
by material group(V023-MATKL) .
Today we use 2 existing options : by Equipment and material .
2. Save and display data .
We did the following steps :
1 . In customizing for Document Management :
a. Maintained a key fields :
table : V023 , tran.code : OMSF , field name : MATKL .
b. Maintained screen object link for V023 .
Our problem is screen number . we used at existing screen - 500 for user exit.
So we get a new tab with material instead of material group .
How I can create a new screen with field material group
for set this screen number in step b ?
May be I need the access key for FUNCTION GROUP CV130
and create this screen by myself ? .
c. Defined Object links for special document type .
2 . Created in se19 at implementation of DOCUMENT_OBJ
with defined filter : V023 .
Regards Helena .Hi Nuno,
how did you solve this problem?
tks -
Problem with new type of Document and WebUI
Hello everyone,
My problem is quite strange. Here it is :
I have created a new subclass of Document using the API, named IFSDocument. So, i created a class IFSDocumentDefinition and a class IFSDocument. Here is the code :
IFSDocumentDefinition :
package fr.sword.ifs.GestionDocument;
public class IFSDocumentDefinition extends DocumentDefinition {
protected LibrarySession ifsSession;
public IFSDocumentDefinition() throws IfsException {
setClassname("IFSDOCUMENT");
public IFSDocumentDefinition(LibrarySession ifsSession) throws IfsException {
this();
this.ifsSession = ifsSession;
IFSDocument :
package fr.sword.ifs.GestionDocument;
public class IFSDocument extends TieDocument{
public IFSDocument(LibrarySession session, Long id, Long classId, S_LibraryObjectData data) throws IfsException {
super(session, id, classId, data);
In this class, i've created a new ClassObject to handle my new type. Here is the method :
public void createIFSDocument(LibrarySession ifsSession) throws IfsException {
DocumentDefinition myDocDef = new DocumentDefinition(ifsSession);
Document doc = (Document)ifsSession.createPublicObject(myDocDef);
ClassObject co = doc.getClassObject();
ClassObjectDefinition cod = new ClassObjectDefinition(ifsSession);
cod.setSuperclass(co);
cod.setSuperclassName(co.getName());
cod.setName("IFSDocument");
ifsSession.setInstallationMode(true);
c = (ClassObject)ifsSession.createSchemaObject(cod);
c.setBeanClasspath("fr.sword.ifs.GestionDocument.IFSDocument");
c.setSelectorClasspath("fr.sword.ifs.GestionDocument.S_IFSDocumentSelector");
c.setServerClasspath("fr.sword.ifs.GestionDocument.S_IFSDocument");
ifsSession.setInstallationMode(false);
I also created two classes named S_IFSDocument and S_IFSDocumentSelector that do nothing special but calling super(). Here is the code :
S_IFSDocument :
package fr.sword.ifs.GestionDocument;
public class S_IFSDocument extends S_TieDocument {
public S_IFSDocument(S_LibrarySession session, java.lang.Long classId) throws IfsException {
super(session, classId);
public S_IFSDocument (S_LibrarySession session, S_LibraryObjectData data) throws IfsException {
super (session, data);
S_IFSDocumentSelector :
package fr.sword.ifs.GestionDocument;
public class S_IFSDocumentSelector extends S_DocumentSelector {
protected S_IFSDocumentSelector(S_LibrarySession session) {
super(session);
protected S_IFSDocumentSelector(S_LibrarySession session, Long classId) throws IfsException {
super(session, classId);
Everything seems to work since i'm able to create new objects of type IFSDocument. I can add custom attributes, put them into folders etc. BUT when i use the web interface, i have the following error message :
oracle.ifs.common.IfsException : IFS-21002: Unable to construct S_LibraryObject for class fr.sword.ifs.GestionDocuments.S_IFSDocument (invalid class path specification)
I don't understand why my classpath is invalid since i simply call super(). So, where is the problem ? Do i have to put the class(es) on the Server ?
By the way, what's the purpose of the Selector class ? Is it related to search ?
Thanks in advance.
Regards,
Guillaume
PS : i'm using iFS 1.1.9 on Oracle 8.1.7 and NT4 sp6Hi Guillaume,
don't know exactly but what i have in mind
is that everything in iFS API that starts
with a S_ is executed at server side, so the
classes should exist there.
You can easily check this if you put your
classes in directory %IFS_HOME%\custom_classes
You are right, the Selector class is for SIMPLE searches, for example:
LibrarySession ifsSession;
String searchCriteria = PublicObject.NAME_ATTRIBUTE + " = '<someName>'";
Selector mySelector = new Selector(ifsSession, Document.CLASS_NAME, searchCriteria);
LibraryObject objs[] = mySelector.getItems();
Regards,
Ralf
null
Maybe you are looking for
-
How to add footer at the end of every page
Hi, I need to add some text at the bottom of every page in my application. I have made a footer region where i have put that text component. I have simply included that footer region as the last element of every jspx page. This shows the footer at th
-
Material account determination and Material valuaion
Hi Please can someone explain the link between MM and FI. We are using Moving Average Price and what I am interested in what accounts are posted when PO, GR, IR, GI, Stock transfers, Physical inventory... also when are the MAC afffected and where are
-
I have to create a grid like form which has editable fields including text box, selects and text areas, and plain text all in each row. e.g. of data ROW 1 COL1 COL2 COL3 COL4 COL5 text select box textbox
-
Time Dimension in Dynamic Reporting
When creating a report that compares a current period (for example 2015.FEB) to the same period in the prior year (2014.FEB), what is the best logic to use in a report? Do I use a local member formula to perform this? I am willing to build in a pro
-
How to know if a UDF form is opened else then using a TRY CATCH ?
I'm looking for any way to find out if the UDF form is visible else then trying to open it in a try catch and if it's not sending a key. This if very ugly, slow and not really my kind. I tried to iterate through all the forms in SBO_Application.Form