<a id="custom-function"></a>
<a id="id1"></a>
# Custom Function

On this page you can create or update a Custom Function.

The Source Code can be C# or SQL and in either case valid Custom Function Code should be entered.

<a id="rave-api-and-v2-conversion"></a>
## Rave API and V2 Conversion

For a saved C# Custom Function, the Rave API its Source Code uses is shown next to the Language: V1, V2, Mixed (both) or None (neither). It describes the Source Code as last saved, and is updated each time the Custom Function is saved.

For a Custom Function that uses the V1 API, V2 Conversion shows how much work converting it takes:

- **Automatic**: every V1 reference has a replacement TrialGrid can make, so it can be converted with the 'Convert to V2' button.
- **Manual**: it uses something with no V2 equivalent, an endpoint Medidata Rave 2025.2.0 removed, or a blacklisted namespace such as database access, so a person has to decide how to replace it.

If converting it has been tried and it couldn't be converted, the reason is shown instead, for example 'No conversion rule'; hover over it for the detail. See [Converting to the V2 API](#custom-function-v2-conversion).

<a id="checking-source-code-for-errors-and-warnings"></a>
## Checking Source Code for errors and warnings

You can validate the Source Code by clicking the button labelled 'Validate'. TrialGrid asks Medidata Designer to compile the Source Code, and shows what Medidata Rave reports: errors, which stop the Custom Function compiling, and warnings, such as API Compatibility warnings for each V1 API reference, with the V2 replacement Medidata Rave suggests. Saving a Custom Function validates it too.

Errors and warnings are listed in the Errors and Warnings menus above the Source Code, and their counts are shown on the menu buttons. Where Medidata Rave gives a line number, the line is marked with an icon in the left-hand side bar, and clicking the message in the menu moves the cursor to that line.

- A count of '?' means there is no result to count: the Source Code has not been validated, or could not be.
- Medidata Rave reports warnings only once the Source Code compiles, so while there are errors the Warnings count is '?'. Warnings may appear once the errors are fixed.
- If you edit the Source Code after validating, the icons and line numbers move with the code, and the menus note that the messages were found before your latest changes. Validate again to refresh them.
- 'Copy all', at the foot of each menu, copies its messages as text, one per line.

The result of validating is kept for 30 days and shown straight away whenever a Custom Function with exactly the same Source Code is opened, by any user. Changing the Source Code, including its layout or comments, needs a new validation.

> **Note:** TrialGrid uses a recent version of Medidata Rave to validate the Source Code. It is possible that older versions of Medidata Rave validate Source Code differently (for example, having fewer restrictions on allowed C# methods). For this reason TrialGrid will allow Source Code with errors to be saved.

<a id="v2-conversion-tab"></a>
## V2 Conversion tab

A saved C# Custom Function has a V2 Conversion tab if your Organization is licensed to convert Custom Functions. Opening it validates the Source Code first if it has no result yet, since the tab reads Medidata Rave's warnings.

For a function using the V1 API the tab lists:

- **Changes**: each V1 reference to edit, with the lines it is on and what replaces it. A V1 type lists every line it is declared or used on, since Medidata Rave reports a type only once. 'Copy changes' copies them as text.
- **Follow-ons**: members that keep their name in V2. They need no edit of their own, and resolve once the declaration of the variable they start from changes to its V2 type.
- **Removed in Rave 2025.2.0**: endpoints that no longer work, with what to use instead.
- **Calls and callers**: the Custom Functions it calls, and those that call it. A call to a function that isn't in the Draft is flagged, and a call by a name worked out when the code runs is shown as such.

Clicking a line number moves the cursor to that line on the Custom Function tab.

For a function that already uses the V2 API, or no API, the tab shows only the calls and callers.

<a id="converting-to-the-v2-api"></a>
<a id="custom-function-v2-conversion"></a>
## Converting to the V2 API

A C# Custom Function that uses the V1 Medidata Rave API can be converted to V2 with the 'Convert to V2' button on the V2 Conversion tab, or several at once from the [Custom Function list](custom_function_list.html.md#custom-function-list). You need permission to edit objects in the Draft, and the Draft must not be locked. The conversion runs in the background, and the progress window has a Cancel button: functions already converted stay converted, and the rest are left as they were.

Converting is licensed separately: your Organization is licensed to convert a number of unique Custom Functions, and without a license neither the V2 Conversion tab nor the list's "Convert to V2 API" action is shown. One conversion is used for each Custom Function converted whose Source Code your Organization has not converted before. Source Code that differs only in its comments or layout counts as the same, so converting a copy of a function in another Draft, or converting a function again after going back to its V1 Source Code, uses none. A function that is flagged and left unchanged uses none either. The V2 Conversion tab shows how many conversions remain, as does the Licenses page of the Organization for those who can manage its users.

If converting a function and the functions it is linked to by calls needs more conversions than remain, none of them is converted, and the progress window says how many were left for that reason. They are not flagged.

Custom Functions that call each other with *PerformCustomFunction* are converted together, so converting one also converts the functions it calls and the functions that call it.

A converted Custom Function is saved only if Medidata Rave compiles it with no V1 references left, and it uses the same strings, calls the same Custom Functions and performs the same actions as before. Otherwise neither it nor any function it is linked to by calls is changed, and each is flagged with the reason. The flag is shown on the V2 Conversion tab, beside V2 Conversion, and in the Custom Function list, and is removed when the Source Code next changes. A flagged function can be converted again at any time; a later version of TrialGrid may convert it.

[How Custom Functions are converted](custom_function_v2_conversion.html.md#custom-function-v2-rules) describes the changes TrialGrid makes.

<a id="editor-buttons"></a>
## Editor buttons

The source code editor has the following buttons to help with editing:

- Search:

  > After clicking the Search button, enter a string in the search box and type Enter. The editor will highlight all instances of that string in the Source Code. The search is case sensitive. Case insensitive (and other more complicated searches) can be done using regular expressions, e.g. /ae/i will perform a case insensitive search for the text 'ae', matching 'ae', 'AE', 'Ae', 'aE'.

- Find Previous

  > Move to the previous result of searching (if any)

- Find Next

  > Move to the next result of searching (if any)

- Replace

  > After clicking the Replace button, enter a string in the Replace box and type Enter. The editor will highlight all instances of that string in the Source Code. You can choose to Replace one-by-one, all or none. The search is case sensitive. Case insensitive (and other more complicated searches) can be done using regular expressions, e.g. /ae/i will perform a case insensitive search for the text 'ae', matching 'ae', 'AE', 'Ae', 'aE'.

- Undo

  > This will undo the most recent, unsaved, change (if any).

- Redo

  > This will undo the most recently undone edit (if any).

- Remove whitespace and comments

  > > Clicking this button will progressively remove more whitespace and comments to reduce the number of characters in the Source Code, which might be useful if approaching the 8000 character Medidata Rave limit.
  > >
  > > Each time the button is clicked it will:
  > >
  > > - remove empty double-spaced lines
  > >
  > >   > If the source code now has fewer characters it will stop, otherwise it will continue:
  > >
  > > - remove spaces from the beginning of lines
  > >
  > >   > If the source code now has fewer characters it will stop, otherwise it will continue:
  > >
  > > - remove single-line comments
  > >
  > >   > If the source code now has fewer characters it will stop, otherwise it will continue:
  > >
  > > - remove multi-line comments
  > >
  > >   > If the source code now has fewer characters it will stop, otherwise it will continue:
  > >
  > > - remove all new lines
  > >
  > >   > No further changes will be made.
  >
  > > **Warning:** Changes made to remove whitespace and comments can be undone before the Custom Function is saved but after it has been saved there is no undo or revert option. Use this button with caution!

- Dedent

  > The start of the current source code line will be moved to the left.

- Indent

  > The start of the current source code line will be moved to the right.

- Auto-indent

  > All source code will be automatically indented.

<a id="keyboard-shortcuts"></a>
## Keyboard shortcuts

The source code editor has keyboard shortcuts to assist with search and replace. The keyboard shortcuts are active when the cursor is inside the source code text area.

- Ctrl-F / Cmd-F

  > Start searching

- Ctrl-G / Cmd-G

  > Find next

- Shift-Ctrl-G / Shift-Cmd-G

  > Find previous

- Shift-Ctrl-F / Cmd-Option-F

  > Replace

- Shift-Ctrl-R / Shift-Cmd-Option-F

  > Replace all
  >
  > (Use the tab key to move between the Yes/No/All/Stop options)

- Alt-G

  > Jump to line

<a id="autocomplete"></a>
## Autocomplete

While editing C# Source Code you can display an autocomplete list using Control-Space (press and hold the Control key and then the Space key). This will display a list of C# classes and methods for the Medidata Rave API the Custom Function uses:

- a Custom Function written with the V1 API is offered V1 names, taken from the Medidata Rave [documentation](https://learn.mdsol.com/rave/architect/en/rave-custom-function-whitelist-186523456.html);
- a Custom Function written with the V2 API is offered V2 names: the `Rave` helpers, such as `Rave.Marking`, the V2 types, such as `IDataPoint`, and their members;
- a Custom Function which uses both, or neither yet, is offered both, with `[V1]` after each V1 name.

The list follows the Source Code as it is when you ask for it, so it changes as a Custom Function is converted by hand from one API to the other. Names of the other API which start with the text to the left of the cursor are listed after the Custom Function's own, so the first V2 name can be found in a V1 Custom Function. When names of both APIs are listed, the V1 names have `[V1]` after them.

> **Note:** There is no published list of the V2 API. The V2 names are those Medidata Rave itself has given when validating Custom Functions: the V2 replacement it suggests for each V1 name. The list is not complete, and it grows as more Custom Functions are validated.

The autocomplete list will be filtered using the text to the left of the cursor. For example showing autocomplete for this C# code

```
DataPoint.Enter
```

will display an autocomplete list starting with:

```
DataPoint.Enter(string, string, int)
DataPoint.Enter(string, string, Medidata.Core.Objects.DataEntryState)
DataPoint.Enter(string, string, string, int)
```

You can use the scroll up and down the list using the mouse or keyboard. Typing more characters will filter the list further. You can select an item using the mouse or with the Tab key.

The method signatures are displayed in the autocomplete list but will not be inserted into the code on selection of an item.

> **Note:** V1 classes and methods which are deprecated by Medidata and/or not supported in Medidata Rave EDC (RaveX) are highlighted in red.

> **Note:** A V1 property which can be read but not set in Medidata Rave EDC is shown with `[EDC: set]` after it and is not highlighted.

> **Note:** The autocomplete functionality is not 'intellisense'. It filters the list based on the text to the left of the cursor but does not analyze the code to work out class types. In the following code no autocomplete will be displayed because TrialGrid does not know that 'dp' is a DataPoint
>
> ```
> DataPoint dp = afp.ActionDataPoint;
> dp.Enter
> ```

<a id="custom-function-length"></a>
## Custom Function Length

The number of characters in the Custom Function Source Code will be displayed at the bottom right. Medidata Rave accepts a maximum of 8000 characters. Note that each line break counts as 2 characters in Medidata Rave.

> **Note:** A warning symbol will be displayed next to the number of characters if the number of characters is less than, but close to the 8000 character limit. Sometimes Medidata Rave will not import Custom Functions which are close to 8000 characters in length.
