├── #ID.calc
├── #IDExclude.calc
├── #IDReplace.calc
├── #IDUpdate.calc
├── #IDValue.calc
├── #Merge.calc
├── .gitignore
├── AppleScriptArrayFinal.calc
├── AppleScriptChooseColor.calc
├── AppleScriptChooseDir.calc
├── AppleScriptCreateEventInICal.fmfn
├── AppleScriptDirPath.calc
├── AppleScriptFilePaths.calc
├── AppleScriptFilePathsInDir.calc
├── AppleScriptFilePathsInDirPrompt.calc
├── AppleScriptGetPageSource.calc
├── AppleScriptLDAPLookup.calc
├── AppleScriptMakeDirOnDesktop.calc
├── AppleScriptMountVolume.calc
├── AppleScriptMoveFiles.calc
├── AppleScriptMoveFiles_ShellMethod.calc
├── AppleScriptOpenInSafari.calc
├── AppleScriptPerformScript.calc
├── AppleScriptPerformScripts.calc
├── AppleScriptReadFile.calc
├── AppleScriptSendEmail.calc
├── AppleScriptSort.calc
├── AppleScriptSortFull.calc
├── AppleScriptSystemProfiler
├── ArrayCell.calc
├── ArrayColumn.calc
├── ArrayColumnLoop.calc
├── ArrayCountInColumn.calc
├── ArrayRow.calc
├── ArrayRowLoop.calc
├── ArrayToHTMLTable.calc
├── ArrayToHash.calc
├── ArrayTranspose.calc
├── ArrayTransposeLoop.calc
├── ArrayValueNext.calc
├── Borrowed
├── ListApplyToValues.calc
├── ListCustom.calc
├── ListCustomCombined.calc
├── ListFilterCustom.calc
├── ListFilterValuesByTest
├── ListSort.calc
├── ListSortDates.calc
├── ListSortDatesLoop.calc
├── ListSortDesc.calc
├── ListSortDescLoop.calc
├── ListSortLoop.calc
├── ListUniqueValues.calc
├── ListUniqueValuesCustom.calc
├── TabActive.calc
├── TabFrontMost.calc
├── TabFrontMostLoop.calc
├── TextAsDate.calc
├── TextRandom.calc
├── app.growlMessage.calc
├── date.weekOfYearFiscal.calc
├── domain.formatPhone.calc
├── layout.tabsSelected.calc
├── num.applyToRange.calc
├── text.ascii.fmfn
├── text.maskReplace.calc
└── text.trimCR
├── CodeMerge.calc
├── CodeMergeLinks.calc
├── CommaDelimit.calc
├── ContainerFileName.calc
├── ContainerStorageType.calc
├── DateBuildRangeHeaders.calc
├── DateBuildSearchRange.calc
├── DateMinusMonths.calc
├── DateMonthDays.calc
├── DateMonthName.calc
├── DateMonthNumber.calc
├── DatePadded.calc
├── DateRangeFromLabel.calc
├── DateShortHand.calc
├── DateWeekStart.calc
├── DateWeekdaysInRange.calc
├── DateWorkdaysInMonth.calc
├── DatesFrom.calc
├── DatesFromFull.calc
├── DatesFromLoop.calc
├── DatesHolidayList.calc
├── DatesInRange.calc
├── DatesInRangeFull.calc
├── DatesInRangeLoop.calc
├── Deprecated
├── VarInvalid.calc
└── VarInvalidLoop.calc
├── DialogDataInputs.calc
├── DialogDataInputsLoop.calc
├── EmailCSSForTable.calc
├── ErrorSuppressionOff.calc
├── ErrorSuppressionOffGlobal.calc
├── ErrorSuppressionOn.calc
├── ErrorText.calc
├── ErrorText11.calc
├── ErrorTextAppleScript.calc
├── ErrorTextAutoUpdate.calc
├── ErrorTextSDialog.calc
├── ErrorsAreSuppressed.calc
├── FOCUS-Specific
├── #DialogResult.calc
├── DialogResultsChecked.calc
├── ExtractTableName.calc
├── IDCreate.calc
├── LayoutBasetable.calc
├── MessageDelete.calc
├── MessageRemove.calc
├── ParamQuery.calc
├── ParamQueryRequest.calc
├── TableIDRemove.calc
├── TableIDRemoveLoop.calc
└── dialog.inputCheckboxes.calc
├── FieldIsQualified.calc
├── FieldNameShort.calc
├── FieldNotEmpty.calc
├── FieldOccurrences.calc
├── FieldRepMatch.calc
├── FieldSortValue.calc
├── FieldSortValues.calc
├── FieldSortValuesLoop.calc
├── FieldsEmpty.calc
├── FileNameEncodeForPath.calc
├── FileNameFromPaths.calc
├── FileNameFromPathsLoop.calc
├── FileNameWithExtension.calc
├── FilePathConvert.txt
├── FileSlash.calc
├── FileView.calc
├── FileViewConditional.calc
├── FileViewRaw.calc
├── GetAsBooleanCustom.calc
├── GetRelatedByValue.calc
├── IsMac.calc
├── IsServer.calc
├── IsWebPublished.calc
├── IsWindows.calc
├── JSONArray.calc
├── JSONArrayGet
├── JSONArrayLoop.calc
├── JSONArrayPosition.calc
├── JSONArrayToVariables.calc
├── JSONArrayValue.calc
├── JSONDecode.calc
├── JSONEncode.calc
├── JSONEncodeStringOnly.calc
├── JSONFromHash.calc
├── JSONFromHashNames
├── JSONObject.calc
├── JSONObjectLoop.calc
├── JSONPair.calc
├── JSONPath.calc
├── JSONValue.calc
├── JSONValueNth.calc
├── JSONWhitespace
├── JavaVersion.calc
├── JsonEscapeChars.calc
├── JsonPretty.calc
├── LibField.calc
├── LibText.calc
├── ListAddOrRemove.calc
├── ListAddUnique.calc
├── ListAggregateNthRecordValues.calc
├── ListAggregateRelatedSets.calc
├── ListAppendPrecedingValues.calc
├── ListAppendUnique.calc
├── ListChartRelatedValues.calc
├── ListChunk.calc
├── ListChunkLoop.calc
├── ListContains.calc
├── ListDateFromNumber.calc
├── ListDateToNumber.calc
├── ListFilter.calc
├── ListFilterSub.calc
├── ListFoundValues.calc
├── ListGetValueIndexes.fmfn
├── ListIndex.calc
├── ListIndexContaining.calc
├── ListIndexLoop.calc
├── ListJoin.calc
├── ListModifyValues.calc
├── ListPrependBOM.calc
├── ListRemoveEmptyValues.calc
├── ListRemoveSuccessiveDuplicates.calc
├── ListRemoveSuccessiveDuplicatesLoop.calc
├── ListReplaceValue.calc
├── ListSortByList.calc
├── ListSortByListLoop.calc
├── ListSortByValueList.calc
├── ListSortDates.calc
├── ListStrip.calc
├── ListToggleValue.calc
├── ListTrimAndJoin.calc
├── ListTrimValues.calc
├── ListTrimValuesLoop.calc
├── ListUnique_v2.calc
├── ListWithNull.calc
├── ListWithNullLoop.calc
├── LogAdd.calc
├── LogDelimiter.calc
├── LogExtract.calc
├── LogFormat.calc
├── MVLSet.calc
├── MVLSetList.calc
├── MVLSetListSorted.calc
├── MapRouteURL.calc
├── MenuRevealIsOn.calc
├── MessageInvalidVar.calc
├── NavLayoutRank.calc
├── NavViewLayout.calc
├── NumberAsDollars.calc
├── ParamAssign.calc
├── ParamValidate.calc
├── ParamValidateMessage.calc
├── PathDir.calc
├── PathFileName.calc
├── PathForAppleScript.calc
├── PathForFMP.calc
├── PathForImport.calc
├── PathForOpenURL.calc
├── PathForScriptMaster.calc
├── PathForShell.calc
├── PathForWebViewer.calc
├── PathFromHome.calc
├── PathPosix.calc
├── PathSet.calc
├── PathStripDisk.calc
├── PathStripPrefix.calc
├── PositionIgnoring.calc
├── PositionUnescaped.calc
├── Project-Specific
├── AmountProratedForMonth.calc
├── CodeLabel.calc
├── ConvertFieldContext.calc
├── CriterionDecode.calc
├── DatabaseModule.calc
├── DateFromString.calc
├── EncodeForHTMLScript.calc
├── FieldNameReadable.calc
├── FilePathForWebViewer.calc
├── FilterIsCustom.calc
├── FocusLocationTab.txt
├── GenerateRange.calc
├── LogForField.calc
├── ParamLogForField.calc
├── ParamLogForRelatedField.calc
├── ResourceData.calc
├── ResourceInclude.calc
├── ScriptTriggersAreOff.calc
├── ScriptTriggersOff.calc
├── ScriptTriggersOn.calc
├── TemplateMerge.calc
├── TimeIncrement.calc
├── TooltipQueryTips.calc
├── WebBubbleButtons.calc
├── WeekdaysOffset.calc
├── text.getBetweenAll.calc
└── time.getMicro.calc
├── PythonSendMailScript.calc
├── README
├── RGBToCSS.calc
├── RGBToHex.calc
├── SQLDate.calc
├── SQLDebug.calc
├── SQLField.calc
├── SQLFieldSeparator.calc
├── SQLFunctions.zip
├── SQLResponse.calc
├── SQLRowSeparator.calc
├── SQLString.calc
├── SQLTable.calc
├── ScriptMasterDependent
├── HTMLGetCellRight.calc
├── HTMLGetRow.calc
└── HTMLGetRowCell.calc
├── ScriptTraceAdd.calc
├── ScriptTraceIsOn.calc
├── ScriptTraceOff.calc
├── ScriptTraceOn.calc
├── SecondsAsString.calc
├── SetIfEmpty.calc
├── SetNotEmpty.calc
├── SqFieldListLoop.calc
├── SqGet.calc
├── SqGetByID.calc
├── SqGetColumn.calc
├── SqGetFields.calc
├── SqGetLike
├── SqGetLiteral
├── SqListLoop
├── SqResponseAsDate.calc
├── SqResponseAsDateNumber.calc
├── SqStringSmart.calc
├── StringRepeat.calc
├── StringRepeatLoop.calc
├── StringToList.calc
├── SuperContainerGetFile.calc
├── SuperContainerViewRawTypes.calc
├── SystemProperties.calc
├── TextAsBoolean.calc
├── TextAsDate.calc
├── TextAsDateSub.calc
├── TextBeginsWith.calc
├── TextBetween.calc
├── TextCapitalizeFirstLetters.calc
├── TextCleanQuotes.calc
├── TextClosePosition.fmfn
├── TextEncodeForAppleScript.calc
├── TextEncodeForFilePath.calc
├── TextEncodeForHTML.calc
├── TextEncodeUTF8Hex.calc
├── TextEscapeForCSV.calc
├── TextEscapeSearchChars.calc
├── TextFilterResult.calc
├── TextFilterResult_subA.calc
├── TextFilterToText.calc
├── TextFormatBullets.calc
├── TextFormatLoop.calc
├── TextInjected?.calc
├── TextInsertAtCursor.calc
├── TextIsDate.calc
├── TextMergeTags.calc
├── TextNthNodePosition.calc
├── TextOmitChars.calc
├── TextPadColumn.calc
├── TextPrependWithTimestamp.calc
├── TextProperLines.calc
├── TextRandom.calc
├── TextRepeatWithIncrement.calc
├── TextReplaceString.calc
├── TextReplaceString_sub.calc
├── TextSplit.calc
├── TextStripLeft.calc
├── TextStripRight.calc
├── TextWrapString.calc
├── TimeDurationAsText.calc
├── TimeStampAsZulu.calc
├── TimeStampMicroUTC.calc
├── TimeZone.calc
├── TimestampFromText.calc
├── TimestampFromUnix.calc
├── TimestampMicro.calc
├── TraceAdd.calc
├── TraceAddSQL.calc
├── TraceClear.calc
├── TraceIsOn.calc
├── TraceLog.calc
├── TraceOff.calc
├── TraceOn.calc
├── TrimCR.calc
├── TrimCRLF.calc
├── TrimCRLeft.calc
├── TrimCRRight.calc
├── TrimChar.calc
├── TrimWhitespace.calc
├── TrimWhitespaceLeft.calc
├── URLDecoded.calc
├── URLEncode
├── URLHash.calc
├── URLParam.calc
├── URLSelf.calc
├── UserIsFullAccess.calc
├── VarAssign.calc
├── VarAssign.fmfn
├── VarAssignLoop.calc
├── VarAssignMan.calc
├── VarAssignWithLog.fmfn
├── VarInvalid.calc
├── VarInvalidLoop.calc
├── VarSet.fmfn
├── VarSetFull.calc
├── VarUpdate.fmfn
├── VarValidate.calc
├── VarValidate2.calc
├── VarValidateLoop.calc
├── WebGif.calc
├── WebNavHeader.calc
├── WebNavHeaderSub.calc
├── WebProgressBar.calc
├── WebSpinningIcon.calc
├── WebViewerFieldDisplay.calc
├── Weekdays.calc
├── WindowGetMeasurements.calc
├── WindowSetMeasurements.calc
├── WindowSetMeasurementsSub.calc
├── WorkHoursOffset.calc
├── calc.hideInvalid.calc
├── calc_Let#Assign.calc
├── calc_PortalSelections.calc
├── calc_PythonSendMail.calc
├── calc_StripDisk.calc
├── calc_getApplicationVersion.calc
├── dev.getScriptName.txt
├── dev.layoutNamesPrefixed.calc
├── domain.convertState.calc
├── domain.formatAddress.calc
├── nav.measureWindow.fmfn
├── nav.setWindowSettings.fmfn
├── plugin.dialogResults.calc
├── rec.getValidRelationships.fmfn
├── rec.hasValidRelationships.fmfn
├── rec.sortFieldValue.calc
├── script.logError.calc
├── sqlList.calc
├── test.compareFields.calc
├── test.sortDisplay.calc
├── web.bubbleButtons.calc
├── web.bubbleButtons_pure.calc
├── web.dataStore.calc
├── xml.select.fmfn
├── xml.select_subA.fmfn
├── xml.select_subB.fmfn
├── xml.transform.fmfn
├── xml.update.fmfn
├── xml.verify.fmfn
└── zJSHighlight.calc
/#ID.calc:
--------------------------------------------------------------------------------
1 | "<:" & table & ":=¶" &
2 | listOfIDs & ¶ &
3 | ":>"
4 |
5 | /* __________________________________________________
6 |
7 | NAME: #ID ( table ; listOfIDs )
8 | PURPOSE: Wraps an encoding tag around a list of IDs. When used in conjunction with decoding functions, allows large groups of IDs from the same table to be stuffed into a field containing IDs from many tables, and the quick extraction of just those IDs, or all IDS but those IDs.
9 | EXAMPLES:
10 | #ID ( "PERSON"; "ID1¶ID2¶ID3" ) = "<:PERSON¶ID1¶ID2¶ID3¶:>"
11 | HISTORY:
12 | Created: 2010-02-08 15:54 PT - Will M. Baker
13 | Modified: 2012-09-24 13:33 PT - Donovan Chandler : Made compatible with normal #Value().
14 | */
--------------------------------------------------------------------------------
/#IDExclude.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | tag = "<:" & table & ":=¶" ;
3 | tagStart = Position ( listOfIDs ; tag ; 1 ; 1 ) ;
4 | tagEnd = Position ( listOfIDs ; "¶:>" ; tagStart ; 1 ) + 2 ;
5 | listLength = Length ( listOfIDs )
6 | ] ;
7 |
8 | Case (
9 | PatternCount ( listOfIDs ; tag ) = 0 ; listOfIDs ;
10 | tagEnd ≥ listLength ; Left ( listOfIDs ; tagStart - 2 ) ;
11 | Left ( listOfIDs ; tagStart - 1 ) & Middle ( listOfIDs ; tagEnd + 1 ; listLength )
12 | )
13 |
14 | )
15 |
16 | /* __________________________________________________
17 |
18 | NAME: #IDExclude ( listOfIDs ; table )
19 | PURPOSE: Retrieves a set of IDs from a table-encoded list, excluding the chunk of IDs corresponding to the specified table.
20 | EXAMPLES:
21 |
22 | HISTORY:
23 | Created: 2010-02-08 15:54 PT - Will M. Baker
24 | Modified: 2012-09-24 13:37 PT - Donovan Chandler : Formatting; made compatible with #( )
25 | */
26 |
--------------------------------------------------------------------------------
/#IDReplace.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | all = listOfIDs ;
3 | allFiltered = #IDExclude ( all ; table ) ;
4 | tableOrig = TrimCR ( # ( all ; table ) )
5 | ] ;
6 | List (
7 | #ID ( table ; newValue ) ;
8 | allFiltered
9 | )
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: #IDReplace ( listOfIDs ; table ; newValue )
15 | PURPOSE: Adds or replaces list of ID's for given table.
16 | Modifies order of name-value pairs in favor of using existing functions.
17 | EXAMPLES:
18 |
19 | HISTORY:
20 | Created: 2012-09-24 14:01 PT - Donovan Chandler
21 | Modified:
22 | */
--------------------------------------------------------------------------------
/#IDUpdate.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | all = listOfIDs ;
3 | allFiltered = #IDExclude ( all ; table ) ;
4 | tableOrig = #IDValue ( all ; table ) ;
5 | tableNew =
6 | Case(
7 | /*-- Multiple selection allowed */
8 | multipleSelectionEnabled ;
9 | ListAddOrRemove ( tableOrig ; selectedID );
10 |
11 | /*-- Add or remove single selection */
12 | tableOrig = selectedID ; "" ;
13 |
14 | selectedID
15 | )
16 | ] ;
17 | List (
18 | #ID ( table ; tableNew ) ;
19 | allFiltered
20 | )
21 | )
22 |
23 | /* __________________________________________________
24 |
25 | NAME: #IDUpdate ( listOfIDs ; table ; selectedID ; multipleSelectionEnabled )
26 | PURPOSE: Updates existing list of ID's for given table.
27 | Used to add/remove a single id value.
28 | Modifies order of name-value pairs in favor of using existing functions.
29 | EXAMPLES:
30 |
31 | HISTORY:
32 | Created: 2012-09-24 14:01 PT - Donovan Chandler
33 | Modified:
34 | */
--------------------------------------------------------------------------------
/#IDValue.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | tag = "<:" & table & ":=¶" ;
3 | dataStart = Position ( listOfIDs ; tag ; 1 ; 1 ) + Length ( tag ) ;
4 | dataEnd = Position ( listOfIDs ; "¶:>" ; dataStart ; 1 )
5 | ] ;
6 |
7 | Case (
8 | Position ( listOfIDs ; tag ; 1 ; 1 ) = 0 ; "" ;
9 | Middle ( listOfIDs ; dataStart ; dataEnd - dataStart )
10 | )
11 |
12 | )
13 |
14 | /* __________________________________________________
15 |
16 | NAME: #IDValue ( listOfIDs ; table )
17 | PURPOSE: Retrieves a set of IDs from an encoded list of tables.
18 | EXAMPLES:
19 |
20 | HISTORY:
21 | Created: 2010-02-08 15:54 PT - Will M. Baker
22 | Modified: 2012-09-24 14:40 PT - Donovan Chandler : Formatting; switched parameter order.
23 | */
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Private/
--------------------------------------------------------------------------------
/AppleScriptArrayFinal.calc:
--------------------------------------------------------------------------------
1 | "{" &
2 | Substitute ( TextStripRight ( unenclosedArray ; "," ) ;
3 | [ "}, ¶{" ; "},{" ] ;
4 | [ "},¶{" ; "},{" ] ;
5 | [ "}¶}" ; "}}" ] ;
6 | [ "{¶{" ; "{{"]
7 | )
8 | & "}"
9 |
10 | /* __________________________________________________
11 |
12 | NAME: AppleScriptArrayFinal ( unenclosedArray )
13 | PURPOSE: Formats array for use in AppleScript
14 | Removes carriage returns and extraneous commas
15 | EXAMPLES:
16 | AppleScriptArrayFinal ( "{foo:123},¶{bar:345}," )
17 | = "{{foo:123},{bar:345}}"
18 | HISTORY:
19 | 2014-07-24 08:09 PT - Donovan Chandler
20 | */
--------------------------------------------------------------------------------
/AppleScriptMakeDirOnDesktop.calc:
--------------------------------------------------------------------------------
1 | "tell application \"Finder\"¶
2 | set dirPath to path to desktop¶
3 | make new folder at dirPath with properties {name:\"" & folderName & "\"}¶
4 | end tell"
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | AppleScriptMakeDirOnDesktop ( folderName )
9 |
10 | PURPOSE:
11 | Creates file on user's desktop
12 |
13 | EXAMPLES:
14 |
15 |
16 | HISTORY:
17 | Created: 2011-Jul-22 10h17 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/AppleScriptSort.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | field = sortField ;
3 | order =
4 | Case (
5 | sortDescending ; "descending" ;
6 | "ascending"
7 | ) ;
8 | doc = Get ( FileName )
9 | ] ;
10 |
11 | "tell current layout of document " & "\"" & doc & "\"¶
12 | sort by field " & "\"" & field & "\"" & " in order " & order & "¶
13 | end tell"
14 |
15 | )
16 |
17 | /* —————————————————————————————— //
18 | NAME:
19 | AppleScriptSort ( sortField ; sortDescending )
20 |
21 | PURPOSE:
22 | Provides dynamic sort on Mac OS using AppleScript.
23 |
24 | EXAMPLES:
25 |
26 |
27 | HISTORY:
28 | Created: 2010-May-25 18h16 PST — Donovan A. Chandler
29 |
30 | NOTES:
31 | BEWARE, sortField must be visible on layout!
32 | */
--------------------------------------------------------------------------------
/ArrayCell.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | row =
3 | TextBetween ( rowDelimiter & array & rowDelimiter ;
4 | rowDelimiter ;
5 | rowDelimiter ;
6 | rowIndex
7 | ) ;
8 | cell =
9 | TextBetween ( columnDelimiter & row & columnDelimiter ;
10 | columnDelimiter ;
11 | columnDelimiter ;
12 | columnIndex
13 | )
14 | ] ;
15 | cell
16 | )
17 |
18 | /* __________________________________________________
19 |
20 | NAME: ArrayCell ( array ; columnIndex ; columnDelimiter ; rowIndex ; rowDelimiter )
21 | PURPOSE: Returns cell value from 2-dimensional array
22 | EXAMPLES:
23 | ArrayCell ( "City|State¶Oakland|CA¶Portland|OR" ; 2 ; "|" ; 2 ; ¶ ) = "CA"
24 | HISTORY:
25 | Created: 2012-10-12 19:06 PT - Donovan Chandler
26 | Modified: 2012-05-25 11:27 PT - Donovan Chandler : Added rowDelimiter param; now uses TextBetween( ).
27 | */
--------------------------------------------------------------------------------
/ArrayColumn.calc:
--------------------------------------------------------------------------------
1 | ArrayColumnLoop ( array ; columnIndex ; columnDelimiter ; rowDelimiter ; "" )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: ArrayColumn ( array ; columnIndex ; columnDelimiter ; rowDelimiter )
6 | PURPOSE: Returns entire row from 2-dimensional array.
7 | TESTS:
8 |
9 | HISTORY:
10 | Created: 2011-10-24 19:40 PST — Donovan Chandler
11 | Modified: 2014-03-20 12:22 PDT - Donovan Chandler : Added rowDelimiter parameter.
12 | */
--------------------------------------------------------------------------------
/ArrayCountInColumn.calc:
--------------------------------------------------------------------------------
1 | ValueCount (
2 | FilterValues ( ArrayColumn ( array ; columnIndex ; columnDelimiter ) ; searchString )
3 | )
4 |
5 | /* —————————————————————————————— //
6 | NAME:
7 | ArrayCountInColumn ( array ; searchString ; columnIndex ; columnDelimiter )
8 |
9 | PURPOSE:
10 | Returns number of cells in specified column of a 2-dimensional array that match 'searchString'
11 |
12 | DEPENDENCIES:
13 | Custom Functions: ArrayColumn ( )
14 |
15 | HISTORY:
16 | Created: 2011-Oct-24 20h03 PST — Donovan A. Chandler
17 | */
--------------------------------------------------------------------------------
/ArrayRow.calc:
--------------------------------------------------------------------------------
1 | ArrayRowLoop ( array; searchValue; searchColumn; 1 )
2 |
3 | /*---------------------------------------------------------------------------------------
4 | NAME:
5 | ArrayRow ( array; searchValue; searchColumn )
6 |
7 | PURPOSE:
8 | Wrapper for RowValueSearchLoop(). See that function documentation for details.
9 |
10 | HISTORY:
11 | Created 2010-Mar-22 11h52 PT donovan_c@beezwax.net
12 | ---------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------
/ArrayToHTMLTable.calc:
--------------------------------------------------------------------------------
1 | "
¶" &
2 | Substitute (
3 | array ;
4 | [ rowDelimiter ; " |
¶" ] ;
5 | [ columnDelimiter ; " | " ]
6 | ) &
7 | " |
¶
"
8 |
9 |
10 | /* __________________________________________________
11 |
12 | NAME: ArrayToHTMLTable ( array ; rowDelimiter ; columnDelimiter )
13 | PURPOSE: Converts tabular array into HTML table
14 | EXAMPLES:
15 | ArrayToHTMLTable ( "Animal|Food¶Dragon|livestock" ; "¶" ; "|" )
16 | //= "
17 | Animal | Food |
18 | Dragon | livestock |
19 |
"
20 | HISTORY:
21 | Created: 2013-01-10 11:00 PT - Donovan Chandler
22 | Modified:
23 | */
--------------------------------------------------------------------------------
/ArrayTranspose.calc:
--------------------------------------------------------------------------------
1 | ArrayTransposeLoop ( array ; columnDelimiter ; "" )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | ArrayTranspose ( array ; columnDelimiter )
6 |
7 | PURPOSE:
8 | Inverts axis of tabular array by moving first row to first column and so forth.
9 |
10 | EXAMPLES:
11 | ArrayTranspose ( "A-B-C¶1-2-3" ; "-" )
12 | = "A-1¶B-2¶C-3"
13 |
14 | HISTORY:
15 | Created: 2011-Oct-24 20h21 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/ArrayTransposeLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | column = ArrayColumn ( array ; 1 ; columnDelimiter ) ;
3 | newRow = Substitute ( column ; columnDelimiter ; ¶ ) ;
4 | newArray = If ( not IsEmpty ( previousResults ) ; previousResults & ¶ ) & newRow
5 | ] ;
6 | ArrayTransposeLoop (
7 | RightValues ( array ; ValueCount ( array ) - 1 ) ) ;
8 | columnDelimiter ;
9 | newArray
10 | )
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | ArrayTranspose ( array ; columnDelimiter ; previousResults )
16 |
17 | PURPOSE:
18 | Perform recursion for ArrayTranspose()
19 |
20 | HISTORY:
21 | Created: 2011-Oct-24 20h14 PST — Donovan A. Chandler
22 | */
--------------------------------------------------------------------------------
/ArrayValueNext.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _row = ArrayRow ( array; rowHeader; headerColumn );
3 | _rowNum = ListValueRowNum( Substitute( _row; Tab; ¶ ); searchValue );
4 | _rowNumNext = If( _rowNum > 0; _rowNum + 1; "" )
5 | ];
6 | Case(
7 | //-- Column is valid
8 | _rowNum > 0;
9 | RowValue( _row; _rowNumNext );
10 |
11 | //-- Column not found
12 | ""
13 | )
14 | )
15 |
16 | /*---------------------------------------------------------------------------------------
17 | NAME:
18 | ArrayValueNext ( array ; rowHeader ; headerColumn ; searchValue )
19 |
20 | PURPOSE:
21 | Finds row in array (tab-delimited) that corresponds to rowHeader in headerColumn.
22 | Then returns value from column following searchValue.
23 |
24 | HISTORY:
25 | Created 2010-Mar-22 12h44 donovan_c@beezwax.net
26 |
27 | EXAMPLE:
28 | If $_array =
29 | "A » pear » apple¶
30 | B » ball » bat¶
31 | C » dog » cat¶
32 | B » can » bottle¶"
33 |
34 | where " » " represents tab character, then :
35 |
36 | ArrayValueNext ( $_array ; "B" ; 1 ; "ball" ) returns "bat".
37 | ---------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------
/Borrowed/ListSortDescLoop.calc:
--------------------------------------------------------------------------------
1 | Case(
2 | (ValueCount( list1 ) < 1) or (ValueCount( list2 ) < 1);
3 | Case( ValueCount( list1 ) < 1; list2; list1 );
4 |
5 | GetValue( list1; 1 ) > GetValue( list2; 1 );
6 | GetValue( list1; 1 ) & "¶" &
7 | ListSortDescLoop( RightValues( list1; ValueCount( list1 ) - 1 ); list2);
8 |
9 | GetValue( list2; 1 ) & "¶" &
10 | ListSortDescLoop( list1; RightValues( list2; ValueCount( list2 ) - 1 ) )
11 |
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | ListSortDescLoop( list1; list2 )
17 | v1.1
18 |
19 | PURPOSE:
20 | Merges two sorted lists into a single sorted list. Used by list.sort().
21 |
22 | HISTORY:
23 | Created by Soliant Consulting (See below or FM 8 Functions p. 229)
24 | Modified 2008.06.17 by DChandler for formatting/commenting preference
25 |
26 | INPUT:
27 | Two sorted, return-delimited lists
28 |
29 | OUTPUT:
30 | A single sorted return-delimited list
31 |
32 | Function created by Soliant Consulting
33 | www.soliantconsulting.com
34 |
35 | Released under the Creative Commons Attribution 2.5 License
36 | http://creativecommons.org/licenses/by/2.5/
37 | */
--------------------------------------------------------------------------------
/Borrowed/ListSortLoop.calc:
--------------------------------------------------------------------------------
1 | Case(
2 | (ValueCount( list1 ) < 1) or (ValueCount( list2 ) < 1);
3 | Case( ValueCount( list1 ) < 1; list2; list1 );
4 |
5 | GetValue( list1; 1 ) < GetValue( list2; 1 );
6 | GetValue( list1; 1 ) & "¶" &
7 | ListSortLoop( RightValues( list1; ValueCount( list1 ) - 1 ); list2);
8 |
9 | GetValue( list2; 1 ) & "¶" &
10 | ListSortLoop( list1; RightValues( list2; ValueCount( list2 ) - 1 ) )
11 |
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | ListSortLoop( list1; list2 )
17 | v1.1
18 |
19 | PURPOSE:
20 | Merges two sorted lists into a single sorted list. Used by list.sort().
21 |
22 | HISTORY:
23 | Created by Soliant Consulting (See below or FM 8 Functions p. 229)
24 | Modified 2008.06.17 by DChandler for formatting/commenting preference
25 |
26 | INPUT:
27 | Two sorted, return-delimited lists
28 |
29 | OUTPUT:
30 | A single sorted return-delimited list
31 |
32 | Function created by Soliant Consulting
33 | www.soliantconsulting.com
34 |
35 | Released under the Creative Commons Attribution 2.5 License
36 | http://creativecommons.org/licenses/by/2.5/
37 | */
--------------------------------------------------------------------------------
/Borrowed/TabFrontMost.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | objectList = LayoutObjectNames ( Get ( FileName ) ; Get ( LayoutName ) )
3 | ] ;
4 |
5 | TrimCR ( TabFrontMostLoop ( objectList ; ValueCount ( objectList ) ) )
6 |
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: TabFrontMost ( )
12 | PURPOSE: Returns a list of front-most tab panels on the layout, according to FileMaker's definition of 'active' (i.e. that every tab object always has exactly one active tab panel).
13 | HISTORY:
14 | Created: 2010-A08-27 12:00 PT - Will M. Baker
15 | Modified: 2012-10-17 10:28 PT - Donovan Chandler : Reformatted.
16 | */
--------------------------------------------------------------------------------
/Borrowed/date.weekOfYearFiscal.calc:
--------------------------------------------------------------------------------
1 | Let(
2 | [
3 | TheDate = GetAsDate ( TheDate ) ;
4 | d = Date(MonthOfYearStart; DayOfYearStart; Year(TheDate)) ;
5 | dp = Date(MonthOfYearStart; DayOfYearStart; Year(TheDate) - 1) ;
6 | s = d + Mod(DayOfWeekStart - DayOfWeek( d ) + 3; 7) - 3 ;
7 | sp = dp + Mod(DayOfWeekStart - DayOfWeek( dp ) + 3; 7) - 3 ;
8 | FY_Start = Case( TheDate >= s ; s ; sp )
9 | ] ;
10 | Int( (TheDate - FY_Start)/7) + 1
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | WeekOfYearFiscalCustom ( TheDate ; DayOfWeekStart ; MonthOfYearStart ; DayOfYearStart )
16 |
17 | PURPOSE:
18 | Returns week number of fiscal year (as defined by user)
19 |
20 | EXAMPLES:
21 | WeekOfYearFiscalCustom (
22 | "10/01/2010" ;
23 | 1 ;
24 | 10 ;
25 | 7
26 | ) => 52
27 |
28 | HISTORY:
29 | Created by Jason L. DeLooze, http://www.briandunning.com/cf/147
30 | Modified: 2010-May-18 11h42 PST — Donovan A. Chandler
31 | */
--------------------------------------------------------------------------------
/Borrowed/text.ascii.fmfn:
--------------------------------------------------------------------------------
1 | Let ( ascii = Mod ( Abs ( GetAsNumber ( ascii ) ) ; 256 ) ;
2 | If ( ascii = 0 ; "" ;
3 | Middle ( "☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕" &
4 | "‼\¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./" &
5 | "0123456789|;<=>?@ABCDEFGHIJKLMNOPQ" &
6 | "RSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz" &
7 | "{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø" &
8 | "£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣" &
9 | "║╗╝¢¥┐ü┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊ" &
10 | "ËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´±‗¾¶§" &
11 | "÷¸°¨·¹³²■ " ; ascii ; 1 )
12 | )
13 | )
14 |
15 | /* —————————————————————————————— //
16 | NAME:
17 | text.ascii ( ascii )
18 |
19 | PURPOSE:
20 | Returns the character for the given ascii value 0-255
21 |
22 | EXAMPLES:
23 |
24 |
25 | HISTORY:
26 | Created by Theo Ros. http://www.briandunning.com/cf/285
27 | Adapted: 2010-Aug-20 12h14 PST — Donovan A. Chandler
28 |
29 | NOTE:
30 | Not all fonts are able to display all characters.
31 | These characters show up as square.
32 | */
--------------------------------------------------------------------------------
/Borrowed/text.trimCR:
--------------------------------------------------------------------------------
1 | Let([
2 | _delimiter = "::‡::"
3 | ];
4 |
5 | Substitute(
6 | Trim(
7 | Substitute( textString;
8 | [ " " ; _delimiter ];
9 | [ ¶ ; " " ]
10 | )
11 | );
12 | [ " " ; ¶ ];
13 | [ _delimiter ; " " ]
14 | )
15 | )
16 |
17 | /* —————————————————————————————— //
18 | NAME:
19 | text.trimCR( textString )
20 |
21 | PURPOSE:
22 | Trims leading and trailing carriage returns from textString
23 |
24 | HISTORY:
25 | Created by Charlie (see below)
26 | Modified: 2010-Aug-09 10h17 PST — Donovan A. Chandler for formatting
27 |
28 | ORIGINAL DOCUMENTATION:
29 | This function is published on FileMaker Custom Functions
30 | to check for updates and provide feedback and bug reports
31 | please visit http://www.fmfunctions.com/fid/185
32 |
33 | Prototype: TrimCR( pText )
34 | Function Author: Charlie (http://www.fmfunctions.com/mid/132)
35 | Last updated: 13 January 2009
36 | Version: 1
37 | */
--------------------------------------------------------------------------------
/CodeMergeLinks.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | linked = CodeMerge ( Substitute ( text ; "‡‡CODE[" ; "‡‡CODE_LINK[" ) )
3 | ] ;
4 | CodeMerge ( Substitute ( linked ; "‡‡*CODE[" ; "‡‡CODE[" ) )
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: CodeMergeLinks ( text )
10 | PURPOSE: Merges value from LIBRARY_CODE table into text,
11 | ensuring that links to values are included instead of merging in entire text.
12 | Useful when exporting code from a table.
13 | EXAMPLES:
14 | // Where FOCUS::LIBRARY_CODE_INCLUDE[index] = "Beezwax!"
15 | // Where FOCUS::LIBRARY_CODE_LINK[index] = "http://beezwax.net"
16 | CodeMergeLoop ( "Hello ‡‡CODE[1]‡‡" ) = "http://beezwax.net"
17 | CodeMergeLoop ( "Hello ‡‡CODE_LINK[1]‡‡" ) = "http://beezwax.net"
18 |
19 | HISTORY:
20 | Created: 2012-06-21 12:14 PT - Donovan Chandler
21 | Modified:
22 | */
--------------------------------------------------------------------------------
/CommaDelimit.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~listEncoded = Substitute ( ¶ & theList & ¶ ; ¶ ; "¶|" ) ;
3 | ~listCulled =
4 | Substitute ( ~listEncoded ;
5 | [ "|¶" ; "" ] ;
6 | [ "¶|" ; ¶ ]
7 | ) ;
8 | ~listNew = Middle ( ~listCulled ; 2 ; Length ( ~listCulled ) - 2 )
9 | ];
10 | Substitute ( ~listNew ; "¶" ; ", " )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: CommaDelimit ( theList )
16 | PURPOSE: Replaces returns with commas
17 | EXAMPLES:
18 | List (
19 | CommaDelimit ( "" ) = ""
20 | ; CommaDelimit ( "¶" ) = ""
21 | ; CommaDelimit ( "¶¶" ) = ""
22 | ; CommaDelimit ( "foo¶fum" ) = "foo, fum"
23 | ; CommaDelimit ( "foo¶fum¶" ) = "foo, fum"
24 | ; CommaDelimit ( "¶foo¶fum" ) = "foo, fum"
25 | ; CommaDelimit ( "foo¶¶fum" ) = "foo, fum"
26 | ; CommaDelimit ( "¶¶foo" ) = "foo"
27 | ; CommaDelimit ( "foo¶¶" ) = "foo"
28 | )
29 | HISTORY:
30 | 2014-08-18 15:13 PDT - Donovan Chandler
31 | */
--------------------------------------------------------------------------------
/ContainerFileName.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | type = ContainerStorageType ( containerAsText )
3 | ] ;
4 | Case (
5 | type = "external" ; TextBetween ( containerAsText ; ":" ; "¶" ; 1 ) ;
6 | type = "reference" ; GetValue ( containerAsText ; 1 ) ;
7 | containerAsText
8 | )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: ContainerFileName ( containerAsText )
14 | PURPOSE: Returns file name from container field.
15 | EXAMPLES:
16 | ContainerFileName ( GetAsText ( table::file ) )
17 | HISTORY:
18 | Created: 2012-11-20 17:24 PT - Donovan Chandler
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/ContainerStorageType.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | Left ( containerAsText ; 7 ) = "remote:" ; "external" ;
3 | ValueCount ( containerAsText ) ≥ 2 ; "reference" ;
4 | "local"
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ContainerStorageType ( containerAsText )
10 | PURPOSE: Determines how container data is being stored.
11 | EXAMPLES:
12 | ContainerStorageType ( GetAsText ( table::file ) )
13 | HISTORY:
14 | Created: 2012-11-20 17:22 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/DateMinusMonths.calc:
--------------------------------------------------------------------------------
1 | Date(
2 | Month( theDate ) - monthsToSubtract;
3 | 1;
4 | Year( theDate )
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | DateMinusMonths( theDate; monthsToSubtract )
10 |
11 | PURPOSE:
12 | Returns first day of month x number of months prior to date provided.
13 |
14 | EXAMPLES:
15 | DateMinusMonths( "8/5/09"; 3 ) = "5/1/09"
16 |
17 | HISTORY:
18 | Created: 2010-Sep-14 17h45 PST — Donovan A. Chandler
19 | */
--------------------------------------------------------------------------------
/DateMonthDays.calc:
--------------------------------------------------------------------------------
1 | Day (
2 | Date (
3 | Month ( GetAsDate ( theDate ) ) + 1 ;
4 | 0 ;
5 | Year ( GetAsDate ( theDate ) )
6 | )
7 | )
8 |
9 | /* —————————————————————————————— //
10 | NAME:
11 | DateMonthDays ( theDate )
12 |
13 | PURPOSE:
14 | Returns count of days in month
15 |
16 | EXAMPLES:
17 | DateMonthDays ( "12/1/2010" ) = 31
18 |
19 | HISTORY:
20 | Created: 2010-Dec-20 14h08 PST — Donovan A. Chandler
21 | */
--------------------------------------------------------------------------------
/DateMonthName.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _name_long =
3 | Choose( monthNum;
4 | "";
5 | "January";
6 | "February";
7 | "March";
8 | "April";
9 | "May";
10 | "June";
11 | "July";
12 | "August";
13 | "September";
14 | "October";
15 | "November";
16 | "December"
17 | )
18 | ];
19 | Case(
20 | shortFormat; Left( _name_long; 3 );
21 | _name_long
22 | )
23 | )
24 |
25 | /* —————————————————————————————— //
26 | NAME:
27 | DateMonthName ( monthNum; shortFormat )
28 |
29 | PURPOSE:
30 | Converts month number to full name
31 |
32 | EXAMPLES:
33 | DateMonthName ( 1 ; False ) = "January"
34 | DateMonthName ( 1 ; True ) = "Jan"
35 |
36 | HISTORY:
37 | Created: 2010-Aug-06 19h22 PST — Donovan A. Chandler
38 | */
--------------------------------------------------------------------------------
/DateMonthNumber.calc:
--------------------------------------------------------------------------------
1 | Position (
2 | "xxJanFebMarAprMayJunJulAugSepOctNovDec"
3 | ; Left ( mnthName; 3 )
4 | ; 1
5 | ; 1
6 | ) / 3
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | DateMonthNumber ( mnthName )
11 |
12 | PURPOSE:
13 | Returns month name corresponding to month number.
14 |
15 | EXAMPLES:
16 | DateMonthName ( "February" ) = 2
17 | DateMonthName ( "feb" ) = 2
18 |
19 | HISTORY:
20 | Source: http://www.briandunning.com/cf/805
21 | Author: David Head, uLearnIT .... http://www.ulearnit.com.au/
22 | Adopted: 2011-Mar-25 12h16 PST — Donovan A. Chandler ; with formatting modifications
23 | */
--------------------------------------------------------------------------------
/DatePadded.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~date = GetAsDate ( "1/2/14" ) ;
3 | ~month = Month ( ~date ) ;
4 | ~day = Day ( ~date ) ;
5 | ~year = Year ( ~date )
6 | ] ;
7 | Right ( "0" & ~month ; 2 ) & "/" &
8 | Right ( "0" & ~day ; 2 ) & "/" &
9 | ~year
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: DatePadded ( theDate )
15 | PURPOSE: Pads month and day with zero for single-digit numbers
16 | EXAMPLES:
17 | DatePadded ( "1/2/14" ) = "01/02/2014"
18 | HISTORY:
19 | Created: 2014-02-26 12:21 PT - Donovan Chandler
20 | Modified:
21 | */
--------------------------------------------------------------------------------
/DateShortHand.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _month_full =
3 | Choose( Month( theDate )
4 | ; ""
5 | ; "January"
6 | ; "February"
7 | ; "March"
8 | ; "April"
9 | ; "May"
10 | ; "June"
11 | ; "July"
12 | ; "August"
13 | ; "September"
14 | ; "October"
15 | ; "November"
16 | ; "December"
17 | );
18 | _month_short = Left( _month_full; 3 );
19 | _year_short = Right( Year( theDate ); 2)
20 | ];
21 | Case (
22 | //-- Future tests for format type go here
23 | True;
24 | _month_short & " " & _year_short
25 | )
26 | )
27 |
28 | /* —————————————————————————————— //
29 | NAME:
30 | date.shorthand( theDate ; format )
31 |
32 | PURPOSE:
33 | Returns shorthand format of date
34 |
35 | EXAMPLES:
36 | date.shorthand ( "3/4/10"; "" ) = "Apr 10"
37 |
38 | HISTORY:
39 | Created: 2010-Aug-04 16h27 PST — Donovan A. Chandler
40 | */
--------------------------------------------------------------------------------
/DateWeekStart.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | yearStart = GetAsNumber ( Date ( 1 ; 1 ; yr ) ) ;
3 | weekStart = yearStart + ( weekNum - 2 ) * 7 + 1
4 | ] ;
5 | GetAsDate ( weekStart )
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | DateWeekStart ( weekNum ; yr )
11 |
12 | PURPOSE:
13 | Returns date of beginning of week (on Sunday).
14 |
15 | EXAMPLES:
16 | DayWeekStart ( 2011 ; WeekOfYear ( "1/1/2011" ) )
17 | = "12/26/2010"
18 |
19 | DayWeekStart ( 2011 ; WeekOfYear ( "1/2/2011" ) )
20 | = "1/2/2011"
21 |
22 | HISTORY:
23 | Created: 2011-Jul-14 14h31 PST — Donovan A. Chandler
24 | */
--------------------------------------------------------------------------------
/DateWeekdaysInRange.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | dayTotal =
3 | GetAsNumber ( GetAsDate ( dateEnd ) )
4 | - GetAsNumber ( GetAsDate ( dateStart ) ) + 1 ;
5 | workWeeks = Int ( dayTotal / 7 ) ;
6 | workLeftover = Mod ( dayTotal ; 7 ) - 1 ;
7 | workLeftover = If ( workLeftover < 1 ; 0 ; workLeftover ) ;
8 | workLeftover = workLeftover + If ( workWeeks ≥ 1 ; 1 )
9 | ] ;
10 | workWeeks*5 + workLeftover
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: DateWeekdaysInRange ( dateStart ; dateEnd )
16 | PURPOSE: Returns number of weekdays in given range
17 | EXAMPLES/TESTS:
18 | List (
19 | DateWeekdaysInRange ( "7/1/2013" ; "7/8/2013" ) = 6 /* Mon - Mon */
20 | ; DateWeekDaysInRange ( "2/14/14" ; "2/18/14" ) = 4 /* Tue - Sat */
21 | )
22 | HISTORY:
23 | Created: 2011-03-25 12:52 PT - Donovan Chandler
24 | Modified: 2013-07-09 17:11 PT - Donovan Chandler: Now includes last day in range.
25 | Modified: 2014-02-04 15:45 PT - Donovan Chandler: Fixed bug with ranges less than a week.
26 | */
--------------------------------------------------------------------------------
/DateWorkdaysInMonth.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | dte = GetAsDate ( theDate ) ;
3 | mnth = Month ( dte ) ;
4 | yr = Year ( dte )
5 | ];
6 | DatesInRange (
7 | Date ( mnth ; 1 ; yr ) ;
8 | Date ( mnth + 1 ; 1 ; yr ) - 1 ;
9 | 1 ;
10 | omitDateList
11 | )
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | DateWorkdaysInMonth ( theDate ; omitDateList )
17 |
18 | PURPOSE:
19 | Returns workdays for month of given date
20 |
21 | EXAMPLES:
22 | ValueCount ( DateWorkdaysInMonth ( "12/20/10" ; "12/20/10" ) ) = 22
23 |
24 | HISTORY:
25 | Created: 2010-Dec-20 14h41 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/DatesFrom.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | //-- Build list of valid dates
3 | list_new =
4 | Case (
5 | numberOfDaysToReturn ≠ 0 ;
6 | DatesFromLoop (
7 | GetAsDate ( startDate ) ;
8 | numberOfDaysToReturn ;
9 | omitWeekends ;
10 | ListDateToNumber ( omitDateList ) ;
11 | ""
12 | )
13 | )
14 | ];
15 | //-- Ensure list is sorted ascending
16 | Case (
17 | IsEmpty ( list_new ) ;
18 | "" ;
19 | numberOfDaysToReturn < 0 ;
20 | ListSortDates ( list_new ; 0 ) ;
21 | list_new
22 | )
23 | )
24 |
25 | /* —————————————————————————————— //
26 | NAME:
27 | DatesFrom ( startDate ; numberOfDaysToReturn ; omitWeekends ; omitDateList )
28 |
29 | PURPOSE:
30 | Returns list of dates in range. Excludes weekends and/or holidays if specified.
31 | Pass negative number into numberOfDaysToReturn to end range on startDate.
32 |
33 | EXAMPLES:
34 | DatesFrom ( "10/1/2010" ; 2 ; 1 ; "10/1/2010" ) = "10/4/2010¶10/5/2010"
35 | DatesFrom ( "10/1/2010" ; -2 ; 1 ; "" ) = "9/29/2010¶9/30/2010"
36 |
37 | HISTORY:
38 | Created: 2010-Oct-15 12h06 PST — Donovan A. Chandler
39 |
40 | NOTE:
41 |
42 | */
--------------------------------------------------------------------------------
/DatesFromFull.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | omitDateList = If ( omitHolidays ; DatesHolidayList )
3 | ];
4 | DatesFrom (
5 | startDate ; numberOfDaysToReturn ;
6 | omitWeekends ;
7 | omitDateList
8 | )
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | DatesFromFull (
14 | startDate ; numberOfDaysToReturn ;
15 | omitWeekends ;
16 | omitHolidays
17 | )
18 |
19 | PURPOSE:
20 | Wrapper for DatesFrom() providing better support for toggling multiple sets of omit dates
21 |
22 | EXAMPLES:
23 |
24 |
25 | HISTORY:
26 | Created: 2010-Nov-19 15h07 PST — Donovan Chandler
27 | */
--------------------------------------------------------------------------------
/DatesHolidayList.calc:
--------------------------------------------------------------------------------
1 | FOCUS::HOLIDAY_LIST
2 |
3 | /* __________________________________________________
4 |
5 | NAME: DatesHolidayList
6 | PURPOSE: Returns list of dates considered to be holidays
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2010-10-19 14:11 PST - Donovan A. Chandler
11 | */
--------------------------------------------------------------------------------
/DatesInRange.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | start = GetAsDate ( startDate ) ;
3 | end = GetAsDate ( endDate )
4 | ] ;
5 | Case (
6 | start ≤ end ;
7 | DatesInRangeLoop (
8 | start ;
9 | end ;
10 | omitWeekends ;
11 | ListDateToNumber ( omitDateList ) ;
12 | ""
13 | )
14 | )
15 | )
16 |
17 | /* __________________________________________________
18 |
19 | NAME: DatesInRange ( startDate ; endDate ; omitWeekends ; omitDateList )
20 | PURPOSE: Returns list of dates in range. Excludes weekends and/or holidays if specified.
21 | EXAMPLES:
22 | DatesInRange ( "10/1/2010" ; "10/4/2010" ; 1 ; "10/4/2010" ) = "10/1/2010¶10/5/2010"
23 | HISTORY:
24 | Created: 2010-10-15 12:06 PT - Donovan Chandler
25 | Modified: 2010-11-30 12:07 PT - Donovan Chandler : replaced "omitHoliday" param with "omitDateList"
26 | */
--------------------------------------------------------------------------------
/DatesInRangeFull.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | omitDateListFull =
3 | List (
4 | If ( omitHolidays ; DatesHolidayList ) ;
5 | omitDateList
6 | )
7 | ];
8 | DatesInRange (
9 | startDate ; endDate ;
10 | omitWeekends ;
11 | omitDateListFull
12 | )
13 | )
14 |
15 | /* __________________________________________________
16 |
17 | NAME: DatesInRangeFull ( startDate ; endDate ;
18 | omitWeekends ;
19 | omitHolidays ;
20 | omitDateList
21 | )
22 | PURPOSE: Wrapper for DatesInRange() providing better support for toggling multiple sets of omit dates
23 | EXAMPLES:
24 |
25 | HISTORY:
26 | Created: 2010-11-30 12:15 PT - Donovan Chandler
27 | */
--------------------------------------------------------------------------------
/Deprecated/VarInvalid.calc:
--------------------------------------------------------------------------------
1 | VarInvalidLoop ( listOfVariableNames ; requireAll ; 1 ; "" )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | VarInvalid ( listOfVariableNames ; requireAll )
6 |
7 | PURPOSE:
8 | Returns list of variables with invalid data.
9 |
10 | USAGE:
11 | Supply variable names as text strings (in quotes).
12 | Each line of the parameter must evaluate to a valid value.
13 | To require one of several vars, place them on one line separated by "|".
14 |
15 | EXAMPLES:
16 | Where $_table = "CONTACT", $_id_contact = "?", $_id_student = ""
17 |
18 | VarInvalid ( "$_table" ) = ""
19 |
20 | VarInvalid (
21 | List ( "$_table" ; "$_id_contact | $_id_student" )
22 | ) = "$_id_contact | $_id_student"
23 |
24 | VarInvalid (
25 | "$_table | $_id_student" )
26 | ) = ""
27 |
28 | HISTORY:
29 | Created: 2010-Oct-28 08h04 PST — Donovan Chandler
30 | */
--------------------------------------------------------------------------------
/DialogDataInputs.calc:
--------------------------------------------------------------------------------
1 | DialogDataInputsLoop ( dialogHashContents ; 1 ; "" )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | DialogDataInputs ( dialogHashContents )
6 |
7 | PURPOSE:
8 | Returns DIALOG hash omitting INPUT elements that don't accept data entry.
9 | Built for use with dialog script supporting SimpleDialog.
10 |
11 | EXAMPLES:
12 |
13 |
14 | HISTORY:
15 | Created: 2010-Nov-11 17h43 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/DialogDataInputsLoop.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | input = #NthValue ( dialogHashContents ; "INPUT" ; rep ) ;
3 | type = #Value (input ; "TYPE" ) ;
4 | invalidTypes = "separator¶image¶link¶caption" ;
5 | isValid = not ListContains ( invalidTypes ; type )
6 | ] ;
7 | Case (
8 | IsEmpty ( input ) ; previousResults ;
9 |
10 | DialogDataInputsLoop (
11 | dialogHashContents ;
12 | rep + 1 ;
13 | List ( previousResults ; If ( isValid ; # ( "INPUT" ; input ) ) )
14 | )
15 | )
16 | )
17 |
18 | /* —————————————————————————————— //
19 | NAME:
20 | DialogDataInputsLoop ( dialogHashContents ; rep ; previousResults )
21 |
22 | PURPOSE:
23 | Returns DIALOG hash omitting INPUT elements that don't accept data entry.
24 | Built for use with dialog script supporting SimpleDialog.
25 |
26 | EXAMPLES:
27 |
28 |
29 | HISTORY:
30 | Created: 2010-Nov-11 15h21 PST — Donovan A. Chandler
31 | */
--------------------------------------------------------------------------------
/EmailCSSForTable.calc:
--------------------------------------------------------------------------------
1 | "
12 | "
13 |
14 | // Trailing lines to leave space before attachment
15 |
16 |
17 | /* —————————————————————————————— //
18 | NAME:
19 | EmailCSSForTable ( )
20 |
21 | PURPOSE:
22 | Returns style element for generic tables used in HTML emails.
23 |
24 | EXAMPLES:
25 | "¶
26 | " & EmailCSSForTable & "¶
27 | ¶
28 | ¶
29 | Dear person. Please see table below.
¶
30 | ¶
31 | Name | " & CONTACT::NAME & " |
¶
32 |
¶
33 | ""
34 |
35 | HISTORY:
36 | Created: 2011-Nov-23 14h12 PST — Donovan Chandler
37 | */
--------------------------------------------------------------------------------
/ErrorSuppressionOff.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_errors_suppressed = If ( $$_errors_suppressed = Get ( ScriptName ) ; False ; $$_errors_suppressed )
3 | ] ;
4 | $$_errors_suppressed
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ErrorSuppressionOff ( )
10 | PURPOSE: Causes error suppression to be disabled if it was enabled by the same script.
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2011-10-07 09:47 PST - Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/ErrorSuppressionOffGlobal.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_errors_suppressed = False
3 | ] ;
4 | $$_errors_suppressed
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ErrorSuppressionOffGlobal ( )
10 | PURPOSE: Causes error suppression to be disabled regardless of which script enabled it.
11 | HISTORY:
12 | Created: 2011-10-07 09:47 PST - Donovan A. Chandler
13 | */
--------------------------------------------------------------------------------
/ErrorSuppressionOn.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_errors_suppressed = If ( ErrorsAreSuppressed ; $$_errors_suppressed ; Get ( ScriptName ) )
3 | ] ;
4 | $$_errors_suppressed
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ErrorSuppressionOn ( )
10 | PURPOSE: Causes error suppression to be enabled.
11 | HISTORY:
12 | Created: 2011-10-07 09:47 PST - Donovan A. Chandler
13 | */
--------------------------------------------------------------------------------
/ErrorsAreSuppressed.calc:
--------------------------------------------------------------------------------
1 | not
2 | (
3 | IsEmpty ( $$_errors_suppressed )
4 | or $$_errors_suppressed = 0
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ErrorsAreSuppressed ( )
10 | PURPOSE: Returns 1 (True) if error handling is disabled for file.
11 | For example, if you are looping through records and building a temp error log instead of showing a dialog for each error.
12 | HISTORY:
13 | Created: 2011-10-07 09:44 PST - Donovan A. Chandler
14 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/#DialogResult.calc:
--------------------------------------------------------------------------------
1 | #Value (
2 | #NthResult ( "RESULT" ; resultNumber ) ;
3 | resultType
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | #DialogResult ( resultNumber ; resultType )
9 |
10 | PURPOSE:
11 | Retrieves result from dialog script
12 |
13 | EXAMPLES:
14 |
15 |
16 | HISTORY:
17 | Created: 2010-Jun-28 16h45 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/DialogResultsChecked.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _result_cur = #NthValue ( dialogResults; "RESULT"; startIndex );
3 | _result_cur_value = #Value ( _result_cur; "VALUE" );
4 | _result_cur_menu = #Value ( _result_cur; "TEXT" );
5 | _is_checked = ( _result_cur_value = 1 );
6 |
7 | _result_next = #NthValue ( dialogResults; "RESULT"; startIndex + 1 );
8 | _result_next_value = #Value ( _result_next; "VALUE" )
9 | ];
10 | If ( _is_checked; _result_cur_menu ) &
11 | If ( startIndex < endIndex;
12 | If ( _result_next_value = 1; ¶ ) &
13 | DialogResultsChecked ( dialogResults; startIndex + 1; endIndex )
14 | )
15 | )
16 |
17 | /* —————————————————————————————— //
18 | NAME:
19 | dialog.resultsChecked ( dialogResults; startIndex; endIndex )
20 |
21 | PURPOSE:
22 | Returns return-delimited list of all checkboxes that were checked in the specified dialog results.
23 |
24 | EXAMPLES:
25 |
26 |
27 | HISTORY:
28 | Created: 2010-Jun-23 11h36 PST — Donovan A. Chandler
29 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/LayoutBasetable.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _to = layoutTableOccurrence;
3 | _delim = "_";
4 | _sName = Position ( _to; _delim; 1; 1 ) + 1;
5 | _eName = Position ( _to; _delim; 1; 2 ) - 1
6 | ];
7 | Case (
8 | _sName = 0; _to;
9 | _eName ≤ 0; Middle ( _to; _sName; 9999 );
10 | Middle ( _to; _sName; _eName - _sName + 1 )
11 | )
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | LayoutBasetable ( layoutTableOccurrence )
17 |
18 | PURPOSE:
19 | Returns name of basetable corresponding to current layout. Used with table array.
20 |
21 | EXAMPLES:
22 |
23 |
24 | HISTORY:
25 | Created: 2010-Jul-13 13h33 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/MessageDelete.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | name = itemFieldOrName ;
3 | field = GetFieldName ( name ) ;
4 | field =
5 | If (
6 | not IsEmpty ( field ) and field ≠ "?";
7 | TableOccurrenceBaseTable ( FieldTableOccurrence ( field ) )
8 | ) ;
9 | reference =
10 | Case (
11 | not IsEmpty ( name ) ; name ;
12 | not IsEmpty ( field ) ; Proper ( field ) ;
13 | "record"
14 | )
15 | ] ;
16 | "Delete " & reference & "?" & ¶ & ¶ &
17 | "There is no undo for this action."
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | MessageDelete ( itemFieldOrName )
23 |
24 | PURPOSE:
25 | Returns text message for use in deletion dialogs.
26 |
27 | EXAMPLES:
28 | MessageDelete ( CONTACT_FOCUS::NAME )
29 |
30 | HISTORY:
31 | Created: 2010-Sep-07 12h00 PST — Donovan A. Chandler
32 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/MessageRemove.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | name = itemFieldOrName ;
3 | field = GetFieldName ( name ) ;
4 | field =
5 | If (
6 | not IsEmpty ( field ) and field ≠ "?";
7 | TableOccurrenceBaseTable ( FieldTableOccurrence ( field ) )
8 | ) ;
9 | reference =
10 | Case (
11 | not IsEmpty ( name ) ; name ;
12 | not IsEmpty ( field ) ; Proper ( field ) ;
13 | "record"
14 | )
15 | ] ;
16 | "Remove " & reference & "?" & ¶ & ¶ &
17 | "There is no undo for this action."
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | MessageRemove ( itemFieldOrName )
23 |
24 | PURPOSE:
25 | Returns text message for use in dialogs when deleting join records.
26 |
27 | EXAMPLES:
28 | MessageRemove ( CONTACT_FOCUS::NAME )
29 |
30 | HISTORY:
31 | Created: 2010-Sep-07 12h00 PST — Donovan A. Chandler
32 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/ParamQuery.calc:
--------------------------------------------------------------------------------
1 | # ( "QUERY" ;
2 | # ( "REQUEST" ;
3 | # ( "OMIT" ; omit ) &
4 | # ( "CRITERION" ;
5 | # ( "FIELD" ; fieldName ) &
6 | # ( "VALUE" ; searchValue )
7 | )
8 | )
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | ParamQuery ( fieldName ; searchValue ; omit )
14 |
15 | PURPOSE:
16 | Constructs QUERY parameter using inputs.
17 | Used with "t filter" and related scripts.
18 |
19 | EXAMPLES:
20 | ParamQuery ( "CONTACT::TYPE" ; "Client" ; 0 )
21 |
22 | HISTORY:
23 | Created: 2011-Jan-06 11h58 PST — Donovan A. Chandler
24 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/ParamQueryRequest.calc:
--------------------------------------------------------------------------------
1 | # ( "REQUEST" ;
2 | # ( "OMIT" ; omit ) &
3 | # ( "CRITERION" ;
4 | # ( "FIELD" ; fieldName ) &
5 | # ( "VALUE" ; searchValue )
6 | )
7 | )
8 |
9 | /* —————————————————————————————— //
10 | NAME:
11 | ParamQueryRequest ( fieldName ; searchValue ; omit )
12 |
13 | PURPOSE:
14 | Constructs REQUEST of QUERY parameter using inputs.
15 | Used with "t filter" and related scripts.
16 |
17 | EXAMPLES:
18 | ParamQueryRequest ( "CONTACT::TYPE" ; "Client" ; 0 )
19 |
20 | HISTORY:
21 | Created: 2011-Jan-06 11h58 PST — Donovan A. Chandler
22 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/TableIDRemove.calc:
--------------------------------------------------------------------------------
1 | TableIDRemoveLoop ( table ; FocusList )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | TableIDRemove ( table )
6 |
7 | PURPOSE:
8 | Returns the list of focused IDs, but without the ID for the specified table. If the ID is not present, the list will be returned as is. Note that each row must be parsed, because we only know the table we are looking for, not a specific ID.
9 | DISABLED -> We assume that only one ID is in focus for the specified table, and thus only attempt to remove the first ID we find.
10 |
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2010-Jan-29 17h00 PST — Will M. Baker
15 | Modified: 2010-Sep-22 16h25 PST — Donovan Chandler : Now removes multiple ID's
16 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/TableIDRemoveLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | #_list = listOfIDs ;
3 | #_id = TableIDRetrieve ( table ) ;
4 | #_row = ListValueRowNum ( #_list ; #_id ) ;
5 | #_list_new =
6 | Case (
7 | #_row > 0 ;
8 | LeftValues ( #_list ; #_row - 1 ) & RightValues ( #_list ; ValueCount ( #_list ) - #_row ) ;
9 | #_list
10 | )
11 | ] ;
12 | Case (
13 | ListValueRowNum ( #_list_new ; #_id ) > 0 ;
14 | TableIDRemoveLoop ( table ; #_list_new ) ;
15 |
16 | #_list_new
17 | )
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | TableIDRemoveLoop ( table ; listOfIDs )
23 |
24 | PURPOSE:
25 | Returns the list of focused IDs, but without the ID for the specified table. If the ID is not present, the list will be returned as is. Note that each row must be parsed, because we only know the table we are looking for, not a specific ID.
26 | DISABLED -> We assume that only one ID is in focus for the specified table, and thus only attempt to remove the first ID we find.
27 |
28 | EXAMPLES:
29 |
30 | HISTORY:
31 | Created: 2010-Jan-29 17h00 PST — Will M. Baker
32 | Modified: 2010-Sep-22 16h25 PST — Donovan Chandler : Modified into recursive subscript
33 | */
--------------------------------------------------------------------------------
/FOCUS-Specific/dialog.inputCheckboxes.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _label_list = listOfLabels;
3 | _value_list = listOfValues;
4 | _label_cur = GetValue ( _label_list; 1 );
5 | _value_cur = GetValue ( _value_list; 1 );
6 | _label_count = ValueCount ( _label_list )
7 | ];
8 | Case (
9 | not IsEmpty ( _label_cur );
10 | # ( "INPUT" ;
11 | # ( "TYPE" ; "checkbox" ) &
12 | # ( "LABEL" ; _label_cur ) &
13 | # ( "DEFAULT_VALUE" ; _value_cur ) &
14 | # ( "DEFAULT_IS_VALID" ; 1 )
15 | )
16 | )
17 | & Case (
18 | _label_count > 1;
19 | ¶ & DialogInputCheckboxes (
20 | RightValues ( _label_list; _label_count - 1 );
21 | RightValues ( _value_list; _label_count - 1 )
22 | )
23 | )
24 | )
25 |
26 | /* —————————————————————————————— //
27 | NAME:
28 | DialogInputCheckboxes ( listOfLabels ; listOfValues )
29 |
30 | PURPOSE:
31 | Constructs input parameter for creating a checkbox set within a dialog.
32 |
33 | EXAMPLES:
34 |
35 |
36 | HISTORY:
37 | Created: 2010-Jun-23 11h04 PST — Donovan A. Chandler
38 |
39 | NOTES:
40 | listOfValues parameter may contain empty or missing values so long as the existing values correlate in position to their respective labels.
41 | */
--------------------------------------------------------------------------------
/FieldIsQualified.calc:
--------------------------------------------------------------------------------
1 | PatternCount ( fieldName ; "::" ) > 0
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | FieldIsQualified ( fieldName )
6 |
7 | PURPOSE:
8 | Returns True if field name is fully qualified (contains table name)
9 |
10 | EXAMPLES:
11 | FieldIsQualified ( GetFieldName ( CONTACT::NAME ) ) = 1
12 | FieldIsQualified ( "NAME" ) = 0
13 | FieldIsQualified ( "" ) = 0
14 |
15 | HISTORY:
16 | Created: 2011-Jan-25 14h59 PST — Donovan A. Chandler
17 | */
--------------------------------------------------------------------------------
/FieldNameShort.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | tableEnd = Position ( fieldName ; "::" ; 1 ; 1 ) ;
3 | field =
4 | Case (
5 | tableEnd = 0 ;
6 | fieldName ;
7 | Middle ( fieldName ; tableEnd + 2 ; 999 )
8 | )
9 | ] ;
10 | Trim ( field )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: FieldNameShort ( fieldName )
16 | PURPOSE: Returns name of field without table name
17 | EXAMPLES:
18 | FieldNameShort ( "CONTACT::NAME" ) = "NAME"
19 | HISTORY:
20 | Created: 2010-11-02 08:59 PST - Donovan A. Chandler
21 | */
22 |
--------------------------------------------------------------------------------
/FieldNotEmpty.calc:
--------------------------------------------------------------------------------
1 | Let ( [
$fields = listOfFieldNames ;
ex =
"Let ( [ value = GetField ( GetValue ( $fields ; [n] ) )
] ; If ( value = \"?\" ; \"?\" ; not IsEmpty ( value ) )
)" ;
result = ListCustom ( 1 ; ValueCount ( $fields ) ; ex )
] ;
If (
Position ( result ; "?" ; 1 ; 1 ) ; "?" ;
Evaluate ( Substitute ( result ; ¶ ; "+" ) )
)
)
/* —————————————————————————————— //
NAME:
FieldNotEmpty ( listOfFieldNames )
PURPOSE:
Given list of field names, returns count of fields that contain a value.
EXAMPLES:
FieldNotEmpty ( List (
GetFieldName ( CONTACT::NAME_FIRST ) ;
GetFieldName ( CONTACT::NAME_LAST ) ;
GetFieldName ( CONTACT::TITLE )
) )
= 1 if NAME_FIRST is the only field with a value
= "?" if fields are not related
HISTORY:
Created: 2011-Sep-30 13h55 PST — Donovan A. Chandler
*/
--------------------------------------------------------------------------------
/FieldOccurrences.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~tableEnd = Position ( fieldName ; "::" ; 1 ; 1 ) ;
3 | ~fieldName = Middle ( fieldName ; If ( ~tableEnd ; ~tableEnd + 2 ; 1 ) ; 99 ) ;
4 | ~query =
5 | "SELECT TableName FROM filemaker_fields" &
6 | "¶WHERE FieldName = ?" &
7 | //-- Remove all tables with "__" in name
8 | "¶AND TableName NOT LIKE '%\_\_%'"
9 | ] ;
10 | ExecuteSQL ( ~query ; "" ; "¶" ; ~fieldName )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: FieldOccurrences ( fieldName )
16 | PURPOSE: Returns list of tables containing specified field.
17 | Contains additional logic to filter out all but "anchor" table occurrences.
18 | EXAMPLES:
19 | FieldOccurrences ( "ID_COMPANY" ) //= "CONTACT¶INVOICE" where those tables have ID_COMPANY field
20 | HISTORY:
21 | Created: 2013-05-09 14:26 PT - Donovan Chandler
22 | Modified:
23 | */
--------------------------------------------------------------------------------
/FieldRepMatch.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | /*
3 | rep = 1 ;
4 | repeatingField = FOCUS::NAV_SUB_LAYOUT_LIST_REP ;
5 | matchValue = "Equipment List" ;
6 | */
7 | ~repContent = GetRepetition ( repeatingField ; startingRep ) ;
8 | ~repMatched = ListContains ( ~repContent ; matchValue )
9 | ] ;
10 | Case (
11 | //-- Exceeded rep range
12 | ~repContent = "?" ; "" ;
13 |
14 | //-- Matched, return repetition/index
15 | ~repMatched ; startingRep ;
16 |
17 | //-- Iterate to next repetition, if still within permitted rep range
18 | startingRep < repMax ; FieldRepMatch ( repeatingField ; matchValue ; startingRep + 1 ; repMax )
19 | )
20 | )
21 |
22 | /* __________________________________________________
23 |
24 | NAME: FieldRepMatch ( repeatingField ; matchValue ; startingRep ; maxRep )
25 | PURPOSE: Returns repetition of field containing a line that matches matchValue
26 | EXAMPLES:
27 |
28 | HISTORY:
29 | Created: 2013-05-16 09:40 PT - Donovan Chandler
30 | Modified:
31 | */
--------------------------------------------------------------------------------
/FieldSortValues.calc:
--------------------------------------------------------------------------------
1 | FieldSortValuesLoop ( fieldList ; useForDescSort ; ValueCount ( fieldList ) ; 1 )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: FieldSortValues ( fieldList ; useForDescSort )
6 | PURPOSE: Given list of field names, returns list of values that are sortable as text.
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2013-03-04 08:13 PT - Donovan Chandler
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/FieldSortValuesLoop.calc:
--------------------------------------------------------------------------------
1 | If (
2 | rep > repMax ; "" ;
3 | Let ( [
4 | field = GetValue ( fieldList ; rep ) ;
5 | tableIndex = TableIndex ( FieldTableOccurrence ( field ) ) ;
6 | descSortIsOn = GetValue ( $$_sort_desc[tableIndex] ; rep )
7 | ] ;
8 | List (
9 | FieldSortValue ( field ; useForDescSort ; descSortIsOn ) ;
10 | FieldSortValuesLoop ( fieldList ; useForDescSort ; repMax ; rep + 1 )
11 | )
12 | )
13 | )
14 |
15 | /* __________________________________________________
16 |
17 | NAME: FieldSortValuesLoop ( fieldList ; useForDescSort ; repMax ; rep )
18 | PURPOSE: Given list of field names, returns list of field values that are sortable as text.
19 | EXAMPLES:
20 |
21 | NOTES: Be sure that the table occurrence of the fieldList values matches the evaluation context calculation in the sort field.
22 | HISTORY:
23 | Created: 2013-03-04 08:13 PT - Donovan Chandler
24 | Modified:
25 | */
--------------------------------------------------------------------------------
/FieldsEmpty.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $fields = listOfFieldNames ;
3 | ex =
4 | "Let ( [ name = GetValue ( $fields ; [n] )
5 | ; value = GetField ( name )
6 | ] ; If ( IsEmpty ( value ) or value = \"?\" ; name )
7 | )" ;
8 | result = ListCustom ( 1 ; ValueCount ( $fields ) ; ex )
9 | ] ;
10 | result
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | FieldsEmpty ( listOfFieldNames )
16 |
17 | PURPOSE:
18 | Given list of field names, returns list of fields that are empty or unrelated.
19 |
20 | EXAMPLES:
21 | Given that NAME_FIRST is the only field containing a value...
22 |
23 | FieldsEmpty ( List (
24 | GetFieldName ( CONTACT::NAME_FIRST ) ;
25 | GetFieldName ( CONTACT::NAME_LAST ) ;
26 | GetFieldName ( CONTACT::TITLE )
27 | ) )
28 | = "CONTACT::NAME_LAST¶CONTACT::TITLE"
29 |
30 | HISTORY:
31 | Created: 2011-Nov-23 11h59 PST — Donovan Chandler
32 | */
--------------------------------------------------------------------------------
/FileNameEncodeForPath.calc:
--------------------------------------------------------------------------------
1 | Substitute (
2 | text ;
3 | [ "/" ; "-" ] ;
4 | [ ¶ ; " " ] ;
5 | [ "|" ; " " ] ;
6 | [ "<" ; " " ] ;
7 | [ ">" ; " " ] ;
8 | [ "..." ; "." ] ;
9 | [ "\"" ; "" ] ;
10 | [ "," ; "" ]
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: FileNameEncodeForPath ( text )
16 | PURPOSE: Ensures file name is valid for use in a path
17 | EXAMPLES:
18 | FileNameEncodeForPath ( "in/out values.pdf" )
19 | // Returns "in-out values.pdf"
20 | HISTORY:
21 | Created: 2013-10-04 12:06 PT - Donovan Chandler
22 | Modified:
23 | */
--------------------------------------------------------------------------------
/FileNameFromPaths.calc:
--------------------------------------------------------------------------------
1 | FileNameFromPathsLoop ( filePaths ; "" )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | FileNameFromPaths ( filePaths )
6 |
7 | PURPOSE:
8 | Extracts file names from list of paths, return list of names
9 |
10 | EXAMPLES:
11 | FileNameFromPaths ( "dir/fileName.txt/¶otherFile.tab" ) = "fileName.txt¶otherFile.tab"
12 |
13 | HISTORY:
14 | Created: 2011-Oct-06 13h19 PST — Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/FileNameFromPathsLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | path = GetValue ( filePaths ; 1 ) ;
3 | dirList = Substitute ( path ; "/" ; ¶ ) ;
4 | count = ValueCount ( dirList ) ;
5 | file = GetValue ( dirList ; count ) ;
6 | file =
7 | Case (
8 | IsEmpty ( file ) ;
9 | GetValue ( dirList ; count - 1 ) ;
10 | file
11 | ) ;
12 | newResult = List ( previousResults ; file )
13 | ] ;
14 | Case (
15 | ValueCount ( filePaths ) > 0 ;
16 | FileNameFromPathsLoop (
17 | RightValues ( filePaths ; ValueCount ( filePaths ) - 1 ) ;
18 | newResult
19 | ) ;
20 | newResult
21 | )
22 | )
23 |
24 | /* —————————————————————————————— //
25 | NAME:
26 | FileNameFromPathsLoop ( filePaths ; previousResults )
27 |
28 | PURPOSE:
29 | Performs recursion for FileNameFromPaths
30 |
31 | EXAMPLES:
32 |
33 |
34 | HISTORY:
35 | Created: 2011-Oct-06 13h09 PST — Donovan A. Chandler
36 | */
--------------------------------------------------------------------------------
/FileNameWithExtension.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | path = Get ( FilePath ) ;
3 | sName = Position ( path ; "/" ; Length ( path ) ; -1 ) + 1
4 | ] ;
5 | Middle ( path ; sName ; 999 )
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | FileNameWithExtension
11 |
12 | PURPOSE:
13 | Returns file name including extension.
14 | Keeps design functions from being fooled by periods in file name.
15 |
16 | EXAMPLES:
17 |
18 |
19 | HISTORY:
20 | Created: 2012-Jan-12 14h06 PST — Donovan A. Chandler
21 | */
--------------------------------------------------------------------------------
/FileSlash.calc:
--------------------------------------------------------------------------------
1 | If (
2 | Abs ( Get ( SystemPlatform ) ) = 2 ; "\\" ;
3 | "/"
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | FileSlash ()
9 |
10 | PURPOSE:
11 | Returns slash character used for current operating system
12 |
13 | EXAMPLES:
14 |
15 |
16 | HISTORY:
17 | Created: 2012-Feb-03 23h29 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/FileView.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | path = folder ;
3 | id = recID ;
4 | nullMessage = "Data:text/html,Please select a file to view" ;
5 | nullPathMessage = "Data:text/html,Path to file on server is invalid"
6 | ];
7 | Case (
8 | IsEmpty ( id ) ; nullMessage ;
9 | IsEmpty ( path ) ; nullPathMessage ;
10 |
11 | SuperContainerGetFile (
12 | SuperContainerUser ;
13 | SuperContainerPassword ;
14 | path ;
15 | height ;
16 | width ;
17 | resolution ; // resolution
18 | style ; // style
19 | backgroundColor ; // bckgndColor
20 | False
21 | )
22 | )
23 |
24 | )
25 |
26 | /* —————————————————————————————— //
27 | NAME:
28 | FileView ( recID ; folder ; height ; width ; resolution ; style ; backgroundcolor )
29 |
30 | PURPOSE:
31 | Fetches file from SuperContainer for viewing in solution.
32 | This is a wrapper for the core function, adding extra validation for record selection, etc.
33 |
34 | EXAMPLES:
35 |
36 |
37 | HISTORY:
38 | Created: 2011-Apr-14 09h52 PST — Donovan A. Chandler
39 | */
--------------------------------------------------------------------------------
/FileViewConditional.calc:
--------------------------------------------------------------------------------
1 | Case (
//-- If PDF, display page preview
ListContains (
typesToShowRaw ;
Filter ( fileType ; "abcdefghijklmnopqrstuvwxyz" )
) ;
FileViewRaw (
FILE::RECORD_ID ;
FILE::FILE_PATH_FROM_BASE_EU
) ;
FileView (
recID ;
folder ;
height ;
width ;
resolution ;
style ;
backgroundcolor
)
)
/* —————————————————————————————— //
NAME:
FileViewConditional ( recID ; folder ; height ; width ; resolution ; style ; backgroundcolor ; fileType ; typesToShowRaw )
PURPOSE:
Fetches file from SuperContainer for viewing in solution.
Shows raw data view if file type is in specified list of types. This allows for centering of images (applet view) and browsing of PDF's (raw data view).
This is a wrapper for the core function, adding extra validation for record selection, etc.
EXAMPLES:
HISTORY:
Created: 2011-Apr-14 09h52 PST — Donovan A. Chandler
*/
--------------------------------------------------------------------------------
/FileViewRaw.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | path = folder ;
3 | id = recID ;
4 | nullMessage = "Data:text/html,Please select a file to view" ;
5 | nullPathMessage = "Data:text/html,Path to file on server is invalid"
6 | ];
7 | Case (
8 | IsEmpty ( id ) ; nullMessage ;
9 | IsEmpty ( path ) ; nullPathMessage ;
10 |
11 | SuperContainerGetFile (
12 | SuperContainerUser ;
13 | SuperContainerPassword ;
14 | path ;
15 | "" ;
16 | "" ;
17 | "" ; // resolution
18 | "" ; // style
19 | "" ; // bckgndColor
20 | True
21 | )
22 | )
23 |
24 | )
25 |
26 | /* —————————————————————————————— //
27 | NAME:
28 | FileViewRaw ( recID ; folder )
29 |
30 | PURPOSE:
31 | Fetches file from SuperContainer for viewing in solution.
32 | Shows raw file instead of applet.
33 | This is a wrapper for the core function, adding extra validation for record selection, etc.
34 |
35 | EXAMPLES:
36 |
37 |
38 | HISTORY:
39 | Created: 2011-May-13 13h16 PST — Donovan Chandler
40 | */
--------------------------------------------------------------------------------
/GetAsBooleanCustom.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | string = "no" or string = "N"; 0;
3 | string = "yes" or string = "Y"; 1;
4 | GetAsBoolean( string )
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | GetAsBooleanCustom ( string )
10 |
11 | PURPOSE:
12 | Returns boolean result from text string
13 |
14 | EXAMPLES:
15 | GetAsBooleanCustom ( "yes" ) = 1
16 |
17 | HISTORY:
18 | Created: 2010-Aug-09 19h21 PST — Donovan A. Chandler
19 | */
--------------------------------------------------------------------------------
/GetRelatedByValue.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ex =
3 | "Let ( [ check = GetNthRecord ( " & compareField & " ; [n] ) " &
4 | "] ; " &
5 | "If ( " &
6 | "check = " & Quote ( compareValue ) & " ; " &
7 | "GetNthRecord ( " & targetField & " ; [n] ) " &
8 | ") )"
9 | ] ;
10 | ListCustom ( 1 ; Count ( GetField ( targetField ) ) ; ex )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: GetRelatedByValue ( targetField ; compareField ; compareValue )
16 | PURPOSE: Returns related values from field where compareField = compareValue
17 | EXAMPLES:
18 | GetRelatedByValue ( "CONTACT::NAME_FIRST" ; "CONTACT::NAME_LAST" ; "Simpson" )
19 | //= "Bart¶Homer¶Lisa¶Maggie¶Marge"
20 | HISTORY:
21 | Created: 2012-03-20 15:44 PST - Donovan Chandler
22 | Modified:
23 | */
--------------------------------------------------------------------------------
/IsMac.calc:
--------------------------------------------------------------------------------
1 | Abs ( Get ( SystemPlatform ) ) = 1
2 |
3 | /* __________________________________________________
4 |
5 | NAME: IsMac ()
6 | PURPOSE: Returns 1 (True) if operating system is Mac OS.
7 | HISTORY:
8 | Created: 2011-05-13 18:18 PST - Donovan A. Chandler
9 | */
--------------------------------------------------------------------------------
/IsServer.calc:
--------------------------------------------------------------------------------
1 | PatternCount ( Get ( ApplicationVersion ) ; "server" ) > 0
2 |
3 | /* __________________________________________________
4 |
5 | NAME: IsServer ( )
6 | PURPOSE: Returns 1 (True) if current user is the server (scheduled script)
7 | NOTES:
8 | For reference on Get ( ApplicationVersion ), see
9 | http://www.filemaker.com/12help/html/func_ref2.32.17.html#1028783
10 | HISTORY:
11 | Created: 2012-03-09 16:04 PT - Donovan Chandler
12 | Modified:
13 | */
--------------------------------------------------------------------------------
/IsWebPublished.calc:
--------------------------------------------------------------------------------
1 | PatternCount ( Get ( ApplicationVersion ) ; "Web Publishing" ) > 0
2 |
3 | /* __________________________________________________
4 |
5 | NAME: IsWebPublished ( )
6 | PURPOSE: Returns TRUE if user is using Instant Web Publishing, otherwise FALSE.
7 | EXAMPLES:
8 |
9 | NOTES:
10 | For reference on Get ( ApplicationVersion ), see
11 | http://www.filemaker.com/12help/html/func_ref2.32.17.html#1028783
12 | HISTORY:
13 | Created: 2012-05-18 15:48 PT - Donovan Chandler
14 | */
--------------------------------------------------------------------------------
/IsWindows.calc:
--------------------------------------------------------------------------------
1 | Abs ( Get ( SystemPlatform ) ) = 2
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | IsWindows ()
6 |
7 | PURPOSE:
8 | Returns true if operating system is Windows
9 |
10 | EXAMPLES:
11 |
12 |
13 | HISTORY:
14 | Created: 2012-Feb-03 22h32 PST — Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/JSONArray.calc:
--------------------------------------------------------------------------------
1 | "[" & JSONArrayLoop ( listOfValues ; ValueCount ( listOfValues ) ; "" ) & "]"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: JSONArray ( listOfValues )
6 | PURPOSE: Converts return-delimited list into JSON array.
7 | Escapes each value, unless it appears to be a JSON object or array.
8 | EXAMPLES:
9 | #Array ( "Oakland¶[\"a\",\"b\"]" ) = "[\"Oakland\",[\"a\",\"b\"]]"
10 | #Array ( "" ) = "[]"
11 | HISTORY:
12 | Created: 2012-05-29 12:18 PT - Donovan Chandler
13 | Modified:
14 | */
--------------------------------------------------------------------------------
/JSONArrayGet:
--------------------------------------------------------------------------------
1 | Let ( [
2 | inner = Trim ( Middle ( jsonArray ; 2 ; Length ( jsonArray ) - 2 ) )
3 | ] ;
4 | TextBetweenNth ( "," & inner & "," ; "," ; "," ; index )
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | JSONArrayGet ( jsonArray ; index )
10 |
11 | PURPOSE:
12 | Returns value from JSON-style array
13 |
14 | EXAMPLES:
15 | JSONArrayGet ( "[9,"b","c"]" ; 1 ) // = 9
16 | JSONArrayGet ( "[1,"b","c"]" ; 2 ) // = "\"b\""
17 |
18 | HISTORY:
19 | Created: 2012-Mar-01 09h03 PST — Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/JSONArrayLoop.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | repMax < 1 or IsEmpty ( listOfValues ) ; previousResults ;
3 | Let ( [
4 | value = JSONEncodeStringOnly ( GetValue ( listOfValues ; 1 ) ) ;
5 | listNew = If ( not IsEmpty ( previousResults ) ; previousResults & "," ) & value ;
6 | listRemaining = MiddleValues ( listOfValues ; 2 ; repMax )
7 | ] ;
8 | JSONArrayLoop ( listRemaining ; repMax - 1 ; listNew )
9 | )
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: JSONArrayLoop ( listOfValues ; repMax ; previousResults )
15 | PURPOSE: Performs recursion for JSONArray( )
16 | EXAMPLES:
17 |
18 | HISTORY:
19 | Created: 2012-05-29 12:23 PT - Donovan Chandler
20 | Modified:
21 | */
--------------------------------------------------------------------------------
/JSONArrayToVariables.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | array = jsonObject ;
3 | name = TextBetween ( array ; "\"" ; ":" ; 1 ) ;
4 | name = TrimChars ( Trim ( name ) ; "\"" ) ;
5 | eName = Position ( array ; name ; 1 ; 1 ) + Length ( name ) ;
6 | value = TextBetween ( array ; ":" ; "," ; 1 ) ;
7 | value = TrimChars ( Trim ( value ) ; "\"" ) ;
8 | sValue = Position ( array ; value ; eName ; 1 ) ;
9 | eValue = If ( sValue > 0 ; Position ( array ; "," ; sValue ; 1 ) ) ;
10 | arrayRemaining = Middle ( array ; eValue ; Length ( array ) + 1 ) ;
11 | arrayRemaining = TrimChars ( Trim ( arrayRemaining ) ; "\"" )
12 | ] ;
13 | VarSet ( name ; value ; useGlobalVars ) +
14 | If ( eValue > 0 and not IsEmpty ( arrayRemaining ) ;
15 | JSONObjectToVariables ( arrayRemaining ; useGlobalVars )
16 | )
17 | )
18 |
19 | /* —————————————————————————————— //
20 | NAME:
21 | JSONObjectToVariables ( jsonObject ; useGlobalVars )
22 |
23 | PURPOSE:
24 | Sets each value of associative array to a variable of same name.
25 |
26 | EXAMPLES:
27 | JSONObjectToVariables ( "\"name\":\"Bob\"" ; true )
28 | // instantiates variable $$_name with value "Bob"
29 |
30 | HISTORY:
31 | Created: 2012-Jan-04 13h33 PST — Donovan Chandler
32 | */
--------------------------------------------------------------------------------
/JSONDecode.calc:
--------------------------------------------------------------------------------
1 | Substitute ( encodedText ;
2 | [ Backslash & QuotationMark ; QuotationMark ] ;
3 | [ Backslash & Backslash ; Backslash ] ;
4 | [ "\¶" ; ¶ ]
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: JSONDecode ( encodedText )
10 | PURPOSE: Returns unquoted form of string encoded using JSONEncode( ) function.
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2012-02-13 13:00 PT - Will M. Baker
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/JSONEncodeStringOnly.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | char1 = Left ( Trim ( text ) ; 1 ) ;
3 | isEscaped = ( char1 = "[" or char1 = "{" )
4 | ] ;
5 | If ( isEscaped ; text ; JSONEncode ( text ) )
6 | )
7 |
8 | /* __________________________________________________
9 |
10 | NAME: JSONEncodeStringOnly ( text )
11 | PURPOSE: Creates quoted string for use in JSON, escaping characters as necessary.
12 | Leaves string in tact if it appears to be a JSON object or array.
13 | EXAMPLES:
14 | #EncodeStringOnly ( "Oakland" ) = "\"Oakland\""
15 | #EncodeStringOnly ( " [\"a\",\"b\"]") = "[\"a\",\"b\"]"
16 | #EncodeStringOnly ( "{\"city\":\"Oakland\"}") = "{\"city\":\"Oakland\"}"
17 | HISTORY:
18 | Created: 2012-05-29 12:54 PT - Donovan Chandler
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/JSONFromHash.calc:
--------------------------------------------------------------------------------
1 | JSONFromHashNames ( text ; #NameAll ( text ) )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | JSONFromHash ( text )
6 |
7 | PURPOSE:
8 | Converts text from hash to JSON
9 |
10 | EXAMPLES:
11 |
12 |
13 | HISTORY:
14 | Created: 2011-Nov-18 13h34 PST — Donovan Chandler
15 | */
--------------------------------------------------------------------------------
/JSONFromHashNames:
--------------------------------------------------------------------------------
1 | Let ( [
2 | _name = GetValue ( listOfNames ; 1 ) ;
3 | _valueRaw = #Value ( text ; _name ) ;
4 | _value =
5 | Case (
6 | Position ( _valueRaw ; ¶ ; 1 ; 1 ) > 0 ;
7 | JSONArray ( _valueRaw ) ;
8 | _valueRaw
9 | ) ;
10 | _listCount = ValueCount ( listOfNames )
11 | ] ;
12 | Case (
13 | not IsEmpty ( _value ) ;
14 | JSONSet ( Lower ( _name ) ; _value )
15 | ) &
16 | Case (
17 | _listCount - 1 > 0 ;
18 | JSONFromHashNames ( text ;
19 | RightValues ( listOfNames ; _listCount - 1 )
20 | )
21 | )
22 | )
23 |
24 | /* —————————————————————————————— //
25 | NAME:
26 | JSONFromHashNames ( text ; listOfNames )
27 |
28 | PURPOSE:
29 | Converts text from hash to JSON for named nodes at top level.
30 |
31 | EXAMPLES:
32 |
33 | HISTORY:
34 | Created: 2010-Aug-18 21h51 PST — Donovan A. Chandler
35 |
36 | NOTES:
37 | Names with empty values will be skipped.
38 | */
--------------------------------------------------------------------------------
/JSONObject.calc:
--------------------------------------------------------------------------------
1 | "{" & JSONObjectLoop ( listOfPairs ; ValueCount ( listOfPairs ) ; "" ) & "}"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: #Object ( listOfPairs )
6 | PURPOSE: Converts return-delimited list of encoded pairs into JSON object.
7 | Assumes each value is already encoded propertly.
8 | EXAMPLES:
9 | Where $_text = "\"city\":\"Oakland\"¶\"\"tags\":[\"bikes\"]"
10 |
11 | #Object ( $_text ) = "{\"city\":\"Oakland\"¶\"\"tags\":[\"bikes\"]}"
12 | #Array ( "" ) = "{}"
13 | HISTORY:
14 | Created: 2012-05-29 13:34 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/JSONObjectLoop.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | repMax < 1 or IsEmpty ( listOfPairs ) ; previousResults ;
3 | Let ( [
4 | value = GetValue ( listOfPairs ; 1 ) ;
5 | listNew = If ( not IsEmpty ( previousResults ) ; previousResults & "," ) & value ;
6 | listRemaining = MiddleValues ( listOfPairs ; 2 ; repMax )
7 | ] ;
8 | JSONObjectLoop ( listRemaining ; repMax - 1 ; listNew )
9 | )
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: JSONObjectLoop ( listOfPairs ; repMax ; previousResults )
15 | PURPOSE: Performs recursion for #Object( )
16 | EXAMPLES:
17 |
18 | HISTORY:
19 | Created: 2012-05-29 13:39 PT - Donovan Chandler
20 | Modified:
21 | */
--------------------------------------------------------------------------------
/JSONPair.calc:
--------------------------------------------------------------------------------
1 | JSONEncode ( name ) & ":" & JSONEncodeStringOnly ( value )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: JSONPair ( name ; value )
6 | PURPOSE: Creates name-value pair in JSON format.
7 | EXAMPLES:
8 | # ( "name" ; "Oakland" ) = "\"name\":\"Oakland\""
9 | # ( "array" ; " [\"a\",\"b\"]") = "\"array\":[\"a\",\"b\"]"
10 | # ( "object" ; "{\"city\":\"Oakland\"}") = "\"object\":{\"city\":\"Oakland\"}"
11 | HISTORY:
12 | Created: 2012-02-13 13:00 PT - Will M. Baker
13 | Modified: 2012-05-29 12:59 PT - Donovan Chandler : Now preserves pre-encoded values.
14 | */
--------------------------------------------------------------------------------
/JSONWhitespace:
--------------------------------------------------------------------------------
1 | List (
2 | Char ( 32 ) // space
3 | ; Char ( 9 ) // horizontal tab
4 | ; Char ( 10 ) // line feed
5 | ; Char ( 11 ) // vertical tab
6 | ; Char ( 12 ) // form feed
7 | ; Char ( 13 ) // carriate return
8 | )
9 |
10 | /* __________________________________________________
11 |
12 | NAME: JSONWhitespace ( )
13 | PURPOSE: Returns list of characters to ignore when searching for JSON values.
14 | HISTORY:
15 | Created: 2013-11-03 22:50 PT - Donovan Chandler
16 | Modified:
17 | */
--------------------------------------------------------------------------------
/JsonEscapeChars.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | GetAsNumber ( text ) = text ; text ;
3 |
4 | Substitute ( Quote ( text ) ;
5 | [ Char ( "/" ) ; "\\/" ] // forward slash
6 | ; [ Char ( 147 ) ; "\"" ] // left curly quote
7 | ; [ Char ( 148 ) ; "\"" ] // right curly quote
8 | ; [ Char ( 8220 ) ; "\"" ] // left curly quote
9 | ; [ Char ( 8221 ) ; "\"" ] // right curly quote
10 |
11 | //-- Collapse lines for efficiency
12 | // ; [ "\¶" ; ":‡:" ]
13 | // ; [ "¶" ; Char ( 32 ) ] // CR to space
14 | // ; [ ":‡:" ; "¶" ]
15 | )
16 | )
17 |
18 | /* __________________________________________________
19 |
20 | NAME: JSONEncode ( text )
21 | PURPOSE: Escapes or removes invalid characters in JSON
22 | EXAMPLES:
23 | JSONEncode ( "Jim said \"what's that \ / ?\"" )
24 | // returns "Jim said \"what's that \\ \/ ?\""
25 | HISTORY:
26 | Created: 2011-07-22 14:14 PT - Donovan Chandler
27 | Modified: 2013-10-20 16:53 PT - Donovan Chandler : Doesn't quote numbers.
28 | NOTES:
29 | Code ( "
30 | " ) = 32
31 | Code ( "¶" ) = 13
32 | */
--------------------------------------------------------------------------------
/JsonPretty.calc:
--------------------------------------------------------------------------------
1 | TextFormatLoop (
2 | text ;
3 | "[¶{" ; // Open chars
4 | "]¶}" ; // Close chars
5 | "," ; // Delimiter chars
6 | "\"¶'" ; // Boundary chars
7 | 0 ; // Indent level
8 | 1 ; // Repetition
9 | Length ( text )
10 | )
11 |
12 | // TextFormatLoop ( text ; openChars ; closeChars ; delimiterChars ; boundaryChars ; indentLevel ; rep ; repMax )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | JSONPretty ( text )
17 |
18 | PURPOSE:
19 | Formats JSON text in readable format
20 |
21 | EXAMPLES:
22 |
23 |
24 | HISTORY:
25 | Created: 2011-Feb-08 11h11 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/LibField.calc:
--------------------------------------------------------------------------------
1 | GetFieldName ( FOCUS::LIBRARY_CODE_REP ) & "[" & index & "]"
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | LibField ( index )
6 |
7 | PURPOSE:
8 | Returns name of field from LIBRARY record with specified index value.
9 |
10 | EXAMPLES:
11 | LibField ( 1 ) = "FOCUS::LIBRARY_CODE_REP[1]"
12 |
13 | HISTORY:
14 | Created: 2010-Aug-24 12h12 PST — Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/LibText.calc:
--------------------------------------------------------------------------------
1 | FOCUS::LIBRARY_CODE_REP[index]
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | LibText ( index )
6 |
7 | PURPOSE:
8 | Returns text from LIBRARY record with specified index value.
9 |
10 | HISTORY:
11 | Created: 2010-Aug-24 12h12 PST — Donovan A. Chandler
12 | */
--------------------------------------------------------------------------------
/ListAddUnique.calc:
--------------------------------------------------------------------------------
1 | List (
2 | lst ;
3 | If ( not ListContains ( lst ; value ) ; value )
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | ListAddUnique ( lst ; value )
9 |
10 | PURPOSE:
11 | Appends value to a return-delimited list if it does not already exist.
12 | Compares entire value (case-insensitive) to determine match.
13 |
14 | EXAMPLES:
15 | ListAddUnique ( "dog¶cat" ; "mouse" ) = "dog¶cat¶mouse"
16 | ListAddUnique ( "dog¶cat" ; "dog" ) = "dog¶cat"
17 | ListAddUnique ( "Dog¶cat" ; "dog" ) = "dog¶cat"
18 | ListAddUnique ( "doggie¶cat" ; "dog" ) = "dog¶cat¶doggie"
19 | ListAddUnique ( "dog¶cat" ; "dog¶doggie" ) = "dog¶cat¶dog¶doggie"
20 |
21 | HISTORY:
22 | Created: 2011-June-27 1h00 PDT — L. Allen Poole
23 | Modified: 2012-Jan-09 17h05 PST — Donovan Chandler ; Now uses List() for handling empty lines.
24 | */
--------------------------------------------------------------------------------
/ListAggregateRelatedSets.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _field = relatedFieldContainingLists ;
3 | _ex = "list.aggregateNthRecordValues ( " & GetFieldName(_field) & "; [n]; " & Quote ( aggregationType ) & " )"
4 | ];
5 | CustomList (
6 | 1 ;
7 | ValueCount ( _field ) ;
8 | _ex
9 | )
10 | )
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | list.aggregateRelatedSets ( relatedFieldContainingLists ; aggregationType )
15 |
16 | PURPOSE:
17 | If a related field has lists of values, this function will take value one from each list and aggregate it (see list.aggregateNthRecordValues). Then it will do the same for the second value, etc.
18 |
19 | EXAMPLES:
20 | list.aggregateNthRecordValues (
21 | "STUDENT_CLASS::ListOfMonthlyTotals";
22 | "Average"
23 | )
24 | = "80.345¶90¶75¶60¶78.113456¶80¶90.09875¶75¶60¶78¶50¶90.01"
25 | = Average totals for January thru December
26 |
27 | HISTORY:
28 | Created: 2010-Jun-11 15h02 PST — Donovan A. Chandler
29 | */
--------------------------------------------------------------------------------
/ListAppendPrecedingValues.calc:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | NAME:
3 | list.appendPrecedingValues( text; searchString )
4 |
5 | PURPOSE:
6 | Returns searchString and all values preceding it in text
7 |
8 | HISTORY:
9 | Created 2010.02.10 by Donovan Chandler
10 |
11 | DEPENDENCIES:
12 | list.getValueIndex()
13 |
14 | ---------------------------------------------------------------------------------------*/
15 | //Show checked value as well as preceding values//
16 |
17 | Let([
18 | lisValues = text;
19 | vValueSel = searchString;
20 | indexValueSel = list.getValueIndex( lisValues; vValueSel; False );
21 | lisValuesResult = LeftValues( lisValues; indexValueSel )
22 | ];
23 | lisValuesResult
24 | )
--------------------------------------------------------------------------------
/ListAppendUnique.calc:
--------------------------------------------------------------------------------
1 | Let (
2 | [
3 | value_exists = Position ( "¶" & currentList & "¶" ; "¶" & value & "¶" )
4 | ] ;
5 | Case (
6 | value_exists ;
7 | currentList ;
8 |
9 | IsEmpty ( value ) ;
10 | currentList ;
11 |
12 | currentList &
13 | If ( Right ( currentList ; 1 ) ≠ ¶ and Length ( currentList ) ; ¶ ) & value
14 | )
15 | )
16 |
17 |
18 | /* —————————————————————————————— //
19 | NAME:
20 | list.appendUnique ( currentList ; value )
21 |
22 | PURPOSE:
23 | Appends value to list if it does not already exist in the list
24 |
25 | EXAMPLES:
26 |
27 |
28 | HISTORY:
29 | Created: 2010-Jul-20 15h18 PST — Donovan A. Chandler
30 | */
--------------------------------------------------------------------------------
/ListChartRelatedValues.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _field = relatedFieldContainingLists ;
3 | _ex = "list.aggregateNthRecordValues ( " & GetFieldName(_field) & "; [n]; " & Quote ( aggregationType ) & " )"
4 | ];
5 | CustomList (
6 | 1 ;
7 | ValueCount ( _field ) ;
8 | _ex
9 | )
10 | )
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | list.aggregateRelatedSets ( relatedFieldContainingLists ; aggregationType )
15 |
16 | PURPOSE:
17 | If a related field has lists of values, this function will take value one from each list and aggregate it (see list.aggregateNthRecordValues). Then it will do the same for the second value, etc.
18 |
19 | EXAMPLES:
20 | list.aggregateNthRecordValues (
21 | "STUDENT_CLASS::ListOfMonthlyTotals";
22 | "Average"
23 | )
24 | = "80.345¶90¶75¶60¶78.113456¶80¶90.09875¶75¶60¶78¶50¶90.01"
25 | = Average totals for January thru December
26 |
27 | HISTORY:
28 | Created: 2010-Jun-11 15h02 PST — Donovan A. Chandler
29 | */
--------------------------------------------------------------------------------
/ListChunk.calc:
--------------------------------------------------------------------------------
1 | ListChunkLoop ( completeList ; chunkSize ; chunkName ; 1 ; "" )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | ListChunk ( completeList ; chunkSize ; chunkName )
6 |
7 | PURPOSE:
8 | Breaks list into series of named values.
9 |
10 | EXAMPLES:
11 | ListChunk ( "1¶2¶3¶4¶5" ; 2 ; "SET" )
12 | = "<:SET:=1¶2:>¶<:SET:=3¶4:>¶<:SET:=5:>"
13 |
14 | HISTORY:
15 | Created: 2011-Mar-24 17h14 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/ListChunkLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | startCur = ( rep - 1 ) * chunkSize + 1 ;
3 | listCur = MiddleValues ( completeList ; startCur ; chunkSize ) ;
4 | listHash = # ( chunkName ; TrimCarriageReturns ( listCur ) ) ;
5 | result = List ( previousResults ; listHash )
6 | ];
7 | Case (
8 | IsEmpty ( listCur ) ; previousResults ;
9 | ListChunkLoop ( completeList ; chunkSize ; chunkName ; rep + 1 ; result )
10 | )
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | ListChunkLoop ( completeList ; chunkSize ; chunkName ; rep ; previousResults )
16 |
17 | PURPOSE:
18 | Performs recursion for ListChunk.
19 |
20 | EXAMPLES:
21 |
22 |
23 | HISTORY:
24 | Created: 2011-Mar-24 16h54 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/ListContains.calc:
--------------------------------------------------------------------------------
1 | not IsEmpty ( FilterValues ( searchValue ; listOfValues ) )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: ListContains ( listOfValues ; searchValue )
6 | PURPOSE: Returns true if listOfValues contains match for searchValue
7 | EXAMPLES:
8 | List (
9 | ListContains ( "foo¶fum¶fap" ; "FOO" ) = 1
10 | ; ListContains ( "foo¶fum¶fap" ; "FOG" ) = 0
11 | ; ListContains ( "foo¶fum¶fap" ; "fu" ) = 0
12 | ; ListContains ( "foo¶fum¶fap" ; "fum¶fap" ) = 1
13 | )
14 | HISTORY:
15 | Created: 2012-03-15 21:59 PST - Donovan Chandler
16 | Modified: 2014-04-09 12:25 PDT - Jeremy Bante : Improving performance
17 | NOTES:
18 | For case sensitive search, use ListFilterCustom()
19 | */
--------------------------------------------------------------------------------
/ListDateFromNumber.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | listCount = ValueCount ( listOfNumbers )
3 | ];
4 |
5 | GetAsDate ( GetAsNumber ( GetValue( listOfNumbers; 1 ) ) ) &
6 | Case (
7 | listCount > 1;
8 | ¶ & ListDateFromNumber ( RightValues ( listOfNumbers; listCount - 1 ))
9 | )
10 |
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | ListDateFromNumber ( listOfNumbers )
16 |
17 | PURPOSE:
18 | Converts a list of numbers into a list of dates. Useful when sorting a list of dates.
19 |
20 | EXAMPLES:
21 |
22 |
23 | HISTORY:
24 | Created: 2010-Sep-07 17h18 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/ListDateToNumber.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | listCount = ValueCount ( listOfDates )
3 | ] ;
4 | GetAsNumber ( GetAsDate ( GetValue( listOfDates; 1 ) ) ) &
5 | Case (
6 | listCount > 1;
7 | ¶ & ListDateToNumber ( RightValues ( listOfDates; listCount - 1 ) )
8 | )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: ListDateToNumber ( listOfDates )
14 | PURPOSE: Converts a list of dates into a list of numbers. Useful when sorting a list of dates.
15 | EXAMPLES:
16 |
17 | HISTORY:
18 | Created: 2010-09-07 17:18 PT - Donovan Chandler
19 | */
20 |
--------------------------------------------------------------------------------
/ListFilter.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | valueCur = GetValue ( valuesToRemove ; 1 ) ;
3 | valueCnt = ValueCount ( valuesToRemove ) ;
4 | listNew = ListFilterSub ( listOfValues ; valueCur )
5 | ] ;
6 | If (
7 | valueCnt ≤ 1 ; listNew ;
8 | ListFilter ( listNew ; RightValues ( valuesToRemove ; valueCnt - 1 ) )
9 | )
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: ListFilter ( listOfValues ; valuesToRemove )
15 | PURPOSE: Returns list with designated value(s) removed.
16 | Preserves all empty lines.
17 | EXAMPLES:
18 | ListFilter ( "Do¶Dog¶¶Cat" ; "Do" ) = "Dog¶¶Cat"
19 | ListFilter ( "Do¶Dog¶Cat" ; "Do¶Cat" ) = "Dog"
20 | ListFilter ( "Do¶Dog¶Cat¶" ; "Dog¶Cat" ) = "Do¶"
21 | HISTORY:
22 | Created: 2012-11-30 10:40 PT - Donovan Chandler
23 | Modified:
24 | */
--------------------------------------------------------------------------------
/ListFilterSub.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | match = ¶ & valueToRemove & ¶ ;
3 | matchStart = Position ( ¶ & listOfValues & ¶ ; match ; 1 ; 1 ) ;
4 | matchStart = matchStart + If ( matchStart > 1 ; -1 ) // Subtract to offset the leading ¶
5 | ] ;
6 | If (
7 | matchStart = 0 ; listOfValues ;
8 | Let ( [
9 | lead = Left ( listOfValues ; matchStart - 1 ) ;
10 | trail = Middle ( listOfValues ; matchStart + Length ( match ) - 1 ; Length ( listOfValues ) )
11 | ] ;
12 | lead & ListFilterSub ( trail ; valueToRemove )
13 | )
14 | )
15 | )
16 |
17 | /* __________________________________________________
18 |
19 | NAME: ListFilterSub ( listOfValues ; valueToRemove )
20 | PURPOSE: Returns list with designated value removed.
21 | Preserves empty lines.
22 | EXAMPLES:
23 | ListFilterSub ( "Do¶Dog¶¶Cat" ; "Do" ) = "Dog¶¶Cat"
24 | ListFilterSub ( "Do¶Dog¶Cat" ; "Do¶Cat" ) = "Do¶Dog¶Cat"
25 | ListFilterSub ( "Do¶Dog¶Cat¶" ; "Dog¶Cat" ) = "Do¶"
26 | HISTORY:
27 | Created: 2012-11-29 21:47 PT - Donovan Chandler
28 | Modified:
29 | */
--------------------------------------------------------------------------------
/ListFoundValues.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | $_field_name = fieldName ;
3 | listFull = ListCustom ( 1 ; Get ( FoundCount ) ; "GetNthRecord ( GetField ( $_field_name ) ; [n])" )
4 | ] ;
5 | Case (
6 | uniqueValuesOnly ;
7 | ListUniqueValues ( listFull ) ;
8 | listFull
9 | )
10 | )
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | ListFoundValues ( fieldName ; uniqueValuesOnly )
15 |
16 | PURPOSE:
17 | Returns values from field for current found set. Not for use on large data sets!
18 |
19 | EXAMPLES:
20 |
21 |
22 | HISTORY:
23 | Created: 2011-Jun-07 15h40 PST — Donovan A. Chandler
24 | */
--------------------------------------------------------------------------------
/ListIndex.calc:
--------------------------------------------------------------------------------
1 | ListIndexLoop ( listOfValues ; matchValue ; 1 ; ValueCount ( listOfValues ) ; False )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: ListIndex ( listOfValues ; matchValue )
6 | PURPOSE: Searches return-delimited list, returning index/value number of first value matching matchValue.
7 | TESTS:
8 | List (
9 | ListIndex ( "lemur¶sky bison¶bear" ; "sky" ) = 0 ;
10 | ListIndex ( "lemur¶sky bison¶bear" ; "bear" ) = 3 ;
11 | ListIndex ( "lemur¶sky bison¶bear" ; "Lemur" ) = 1
12 | )
13 | HISTORY:
14 | Created: 2013-12-09 21:43 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/ListIndexLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~value = GetValue ( listOfValues ; startIndex )
3 | ] ;
4 | Case (
5 | startIndex > indexCount ;
6 | 0 ;
7 | matchCase ;
8 | If ( Exact ( ~value ; matchValue ) ; startIndex ; 0 ) ;
9 | ~value = matchValue ;
10 | startIndex ;
11 | ListIndexLoop ( listOfValues ; matchValue ; startIndex + 1 ; indexCount ; matchCase )
12 | )
13 | )
14 |
15 | /* __________________________________________________
16 |
17 | NAME: ListIndexLoop ( listOfValues ; matchValue ; startIndex ; indexCount ; matchCase )
18 | PURPOSE: Searches return-delimited list, returning index/value number of first value matching matchValue.
19 | TESTS:
20 | List (
21 | ListIndexLoop ( "lemur¶sky bison¶bear" ; "sky" ; 1 ; 3 ; 0 ) = 0 ;
22 | ListIndexLoop ( "lemur¶sky bison¶bear" ; "bear" ; 1 ; 2 ; 0 ) = 0 ;
23 | ListIndexLoop ( "lemur¶sky bison¶bear" ; "bear" ; 1 ; 3 ; 0 ) = 3 ;
24 | ListIndexLoop ( "lemur¶sky bison¶bear" ; "Lemur" ; 1 ; 3 ; 0 ) = 1 ;
25 | ListIndexLoop ( "lemur¶sky bison¶bear" ; "Lemur" ; 1 ; 3 ; 1 ) = 0
26 | )
27 | HISTORY:
28 | Created: 2010-01-29 17:00 PT - Will M. Baker
29 | */
30 |
--------------------------------------------------------------------------------
/ListJoin.calc:
--------------------------------------------------------------------------------
1 | Case (
IsEmpty ( lastDelimiter ) ;
Substitute ( theList ; ¶ ; delimiter ) ;
Let ( [
sLast = Position ( theList ; ¶ ; Length ( theList ) ; -1 ) ;
rough = Replace ( theList ; sLast ; 1 ; lastDelimiter )
] ;
Substitute ( rough ; ¶ ; delimiter )
)
)
/* —————————————————————————————— //
NAME:
ListJoin ( theList ; delimiter ; lastDelimiter )
PURPOSE:
Collapses list into string delimited by provided characters.
EXAMPLES:
ListJoin ( "dog¶cat¶mouse" ; ", " ; " or " )
= "dog, cat or mouse"
ListJoin ( "dog¶cat¶mouse" ; ", " ; "" )
= "dog, cat, mouse"
HISTORY:
Created: 2011-Nov-30 16h43 PST — Donovan A. Chandler
*/
--------------------------------------------------------------------------------
/ListModifyValues.calc:
--------------------------------------------------------------------------------
1 | Case (
2 |
3 | ValueCount ( text ) > 0;
4 | Let ([
5 | vValueCur = LeftValues ( Substitute ( text ; [ "\“" ; "\"" ] ; [ "\”" ; "\"" ] ; [ "\"" ; "\\\""] ) ; 1) ;
6 | exComplete =
7 | Substitute ( expression ;
8 | [ valuePlaceholder ; "\"" & Substitute ( vValueCur ; ¶ ; "" ) & "\"" ]
9 | ) ;
10 | vValEvaluated = Evaluate ( exComplete ) ;
11 | numValuesRem = ValueCount ( text ) - 1
12 | ] ;
13 | Substitute ( vValEvaluated ; "\\\"" ; "\"" )
14 | & If ( numValuesRem > 0 ; ¶ )
15 | & ListModifyValues (
16 | RightValues ( text ; numValuesRem ) ;
17 | valuePlaceholder ;
18 | expression
19 | )
20 | )
21 |
22 | )
23 |
24 | /* __________________________________________________
25 |
26 | NAME: ListModifyValues ( text ; valuePlaceholder ; expression )
27 | PURPOSE: Applies expression to each return-delimited value in text.
28 | EXAMPLES:
29 | ListModifyValues ( "dog¶cat¶mouse"; "[v]"; "Left( [v]; 2 )" ) = "do¶ca¶mo"
30 | HISTORY:
31 | Compliments to Fabrice Nordmann of BH&A for example of this expression evaluation technique
32 | Created: 2010-02-10 00:00 PT - Donovan Chandler
33 | Modified: 2013-04-22 09:39 PT - Donovan Chandler : Updated formatting.
34 | */
--------------------------------------------------------------------------------
/ListPrependBOM.calc:
--------------------------------------------------------------------------------
1 | List (
2 |
3 | If ( startIndex > 1 ; StringRepeat ( Char ( 65279 ) ; startIndex ) )
4 | & GetValue ( theList ; startIndex )
5 |
6 | ; If ( ValueCount ( theList ) > startindex ; ListPrependBOM ( theList ; startIndex + 1 ) )
7 |
8 | )
9 |
10 | /* __________________________________________________
11 |
12 | NAME: ListPrependBOM ( theList ; startIndex )
13 | PURPOSE: Prepends each line with byte order marks. Used to create sorted value lists.
14 | EXAMPLES:
15 |
16 | HISTORY:
17 | Thanks to Lon Cook for pointing me to BOM an Char ( 65279 ).
18 | Created: 2013-08-07 14:42 PT - Donovan Chandler
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/ListRemoveEmptyValues.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | //-- Iterate until all empty rows are removed
3 | PatternCount ( text ; "¶¶" ) > 0 ;
4 | ListRemoveEmptyValues (
5 | Substitute ( text ;
6 | [ "¶¶¶" ; "¶" ] ;
7 | [ "¶¶" ; "¶" ]
8 | )
9 | ) ;
10 |
11 | //-- If list is clean, remove leading/trailing returns
12 | TrimCR ( text )
13 | )
14 |
15 | /* —————————————————————————————— //
16 | NAME:
17 | ListRemoveEmptyValues ( text )
18 |
19 | PURPOSE:
20 | Removes all empty values from list
21 |
22 | EXAMPLES:
23 | ListRemoveEmptyValues ( "¶foo¶¶bar" ) = "foo¶bar"
24 |
25 | HISTORY:
26 | Created: 2010-Sep-06 08h26 PST — Donovan A. Chandler
27 | */
--------------------------------------------------------------------------------
/ListRemoveSuccessiveDuplicates.calc:
--------------------------------------------------------------------------------
1 | ListRemoveSuccessiveDuplicatesLoop ( text ; 1 ; "" )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | ListRemoveSuccessiveDuplicates ( text )
6 |
7 | PURPOSE:
8 | Returns list of values with neighboring duplicates removed.
9 |
10 | EXAMPLES:
11 | ListRemoveNeighboringDuplicates ( "1¶2¶2¶1¶2" ) = "1¶2¶1¶2"
12 |
13 | HISTORY:
14 | Created: 2010-Nov-09 10h17 PST — Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/ListRemoveSuccessiveDuplicatesLoop.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | value_cur = GetValue ( text ; repetition ) ;
3 | value_prev = GetValue ( previousResults ; ValueCount ( previousResults ) ) ;
4 | result_new =
5 | Case (
6 | value_cur ≠ value_prev ;
7 | previousResults & ¶ & value_cur ;
8 | previousResults
9 | )
10 | ];
11 |
12 | Case (
13 | repetition ≥ ValueCount ( text ) ;
14 | ListTrimCR ( result_new ) ;
15 |
16 | ListRemoveSuccessiveDuplicatesLoop ( text ; repetition + 1 ; result_new )
17 | )
18 |
19 | )
20 |
21 | /* —————————————————————————————— //
22 | NAME:
23 | ListRemoveSuccessiveDuplicates ( text ; repetition )
24 |
25 | PURPOSE:
26 | Returns list of values with neighboring duplicates removed.
27 |
28 | EXAMPLES:
29 | ListRemoveSuccessiveDuplicatesLoop ( "1¶2¶2¶1¶2" ; 3 ; "1¶2" ) = "1¶2¶1¶2"
30 |
31 | HISTORY:
32 | Created: 2010-Nov-09 10h17 PST — Donovan A. Chandler
33 | */
--------------------------------------------------------------------------------
/ListReplaceValue.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | lstLen = ValueCount ( lst ) ;
3 | lstGap = index - lstLen ;
4 | padding = If ( lstGap > 0 ; StringRepeatLoop ( "¶" ; 1 ; lstGap ) ) ;
5 | lead = LeftValues ( lst & padding ; index - 1 ) ;
6 | trail = RightValues ( lst ; lstLen - index )
7 | ] ;
8 | lead & newValue & If ( not IsEmpty ( trail ) ; ¶ & trail )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: ListReplaceValue ( lst ; index ; newValue )
14 | PURPOSE: Replaces value at given index in list.
15 | EXAMPLES:
16 |
17 | HISTORY:
18 | Created: 2013-03-03 22:33 PT - Donovan Chandler
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/ListSortByList.calc:
--------------------------------------------------------------------------------
1 | ListSortByListLoop (
2 | listToSort ;
3 | ListUniqueValues ( sortedList ) ;
4 | 1 ;
5 | ValueCount ( sortedList ) ;
6 | ""
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: ListSortByList ( listToSort ; sortedList )
12 | PURPOSE: Sorts list in order designated by another list
13 | EXAMPLES:
14 | NOTES:
15 | Omits values that do not appear in sorted list.
16 | HISTORY:
17 | Created: 2011-05-24 16:07 PT - Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/ListSortByListLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | val = GetValue ( sortedList ; rep )
3 | ];
4 | Case (
5 | rep ≤ rep_max ;
6 | ListSortByListLoop (
7 | listToSort ;
8 | sortedList ;
9 | rep + 1 ;
10 | rep_max ;
11 | TrimCR ( List ( previousResults ; FilterValues ( listToSort ; val ) ) )
12 | ) ;
13 | previousResults
14 | )
15 | )
16 |
17 | /* __________________________________________________
18 |
19 | NAME: ListSortByListLoop ( listToSort ; sortedList ; rep ; rep_max ; previousResults )
20 | PURPOSE: Performs recursive operations for ListSortByList()
21 | EXAMPLES:
22 |
23 | HISTORY:
24 | Created: 2011-05-24 16:02 PT - Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/ListSortByValueList.calc:
--------------------------------------------------------------------------------
1 | ListSortByList (
2 | listToSort ;
3 | ValueListItems ( Get ( FileName ) ; valueListName )
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | ListSortByValueList ( listToSort ; valueListName )
9 |
10 | PURPOSE:
11 | Sorts list by order of values in value list.
12 |
13 | EXAMPLES:
14 |
15 |
16 | HISTORY:
17 | Created: 2011-May-24 16h22 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/ListSortDates.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | numberList = ListDateToNumber ( listOfDates ) ;
3 | numberSorted =
4 | Case (
5 | sortDescending ;
6 | ListSortDesc ( numberList) ;
7 | ListSort ( numberList )
8 | )
9 | ];
10 | ListDateFromNumber ( numberSorted )
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | ListSortDates ( listOfDates ; sortDescending )
16 |
17 | PURPOSE:
18 | Returns a sorted list of dates.
19 |
20 | EXAMPLES:
21 | ListSortDates ( "9/1/10¶10/1/10" ; 1 ) = "10/1/10¶9/1/10"
22 |
23 | HISTORY:
24 | Created: 2010-Sep-07 17h45 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/ListToggleValue.calc:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | NAME:
3 | list.toggleValue( listOfValues ; valueAddOrRemove )
4 |
5 | PURPOSE:
6 | Adds or removes value from theList
7 |
8 | HISTORY:
9 | Created 2010-Mar-31 by Donovan Chandler
10 |
11 | ---------------------------------------------------------------------------------------*/
12 |
13 | Let([
14 | _list = listOfValues;
15 | _string = valueAddOrRemove
16 |
17 | ];
18 |
19 | Case(
20 | //-- If value exists, remove it
21 | ValueCount( FilterValues( _list; _string )) > 0;
22 | list.remove( _list; _string );
23 |
24 | //-- Else, append value
25 | If( IsEmpty( _list ); ""; _list & ¶ ) & _string
26 | )
27 |
28 | )
--------------------------------------------------------------------------------
/ListTrimAndJoin.calc:
--------------------------------------------------------------------------------
1 | Substitute (
2 | ListTrimValues ( text ) ;
3 | ¶ ;
4 | newDelimiter
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | ListTrimAndJoin ( text ; newDelimiter )
10 |
11 | PURPOSE:
12 | Replaces carriage returns in return-delimited list with new delimiter.
13 | Also strips whitespace from ends of each line.
14 |
15 | EXAMPLES:
16 | ListTrimAndJoin ( "dog¶ cat ¶¶mouse¶" ; ", " ) = "dog,cat,mouse"
17 |
18 | HISTORY:
19 | Created: 2011-Mar-08 09h33 PST — Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/ListTrimValues.calc:
--------------------------------------------------------------------------------
1 | ListTrimValuesLoop ( theList ; 1 ; ValueCount ( theList ) )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | ListTrimValues ( theList )
6 |
7 | PURPOSE:
8 | Removes leading and trailing spaces from each value in a list.
9 |
10 | EXAMPLES:
11 |
12 |
13 | HISTORY:
14 | Created: 2011-Feb-02 12h11 PST — Donovan Chandler
15 | */
--------------------------------------------------------------------------------
/ListTrimValuesLoop.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | valueTrimmed = Trim ( GetValue ( theList ; rep ) ) ;
3 | listNew =
4 | List (
5 | ListTrimCR ( LeftValues ( theList ; rep - 1 ) ) ;
6 | valueTrimmed ;
7 | MiddleValues ( theList ; rep + 1 ; 50000 )
8 | )
9 | ] ;
10 | Case (
11 | rep < repMax ;
12 | ListTrimValuesLoop ( listNew ; rep + 1 ; repMax ) ;
13 |
14 | listNew
15 | )
16 | )
17 |
18 | /* —————————————————————————————— //
19 | NAME:
20 | ListTrimValuesLoop ( theList ; rep ; repMax )
21 |
22 | PURPOSE:
23 | Peforms recursion for ListTrimValues
24 |
25 | EXAMPLES:
26 |
27 |
28 | HISTORY:
29 | Created: 2011-Feb-02 12h04 PST — Donovan A. Chandler
30 | */
--------------------------------------------------------------------------------
/ListUnique_v2.calc:
--------------------------------------------------------------------------------
1 | //---- UNDER DEVELOPMENT ----
2 | Let([
3 | _list = theList;
4 | $$_uniqueList_list =
5 | If ( not IsEmpty ( $$_uniqueList_list )
6 | ; $$_uniqueList_list
7 | ; _list
8 | );
9 | $$_uniqueList_rep = $$_uniqueList_rep + 1;
10 |
11 | _list_rev = $$_uniqueList_list;
12 | _rep = $$_uniqueList_rep;
13 | _valueCur = GetValue ( _list)
14 |
15 |
16 | ];
17 | //Replace all subsequent values with null and continue down list
18 | )
19 |
20 | /*---------------------------------------------------------------------------------------
21 | NAME:
22 | list.uniqueValues ( theList )
23 |
24 | PURPOSE:
25 | Returns return-delimited list containing only unique values in the order that they first appear.
26 |
27 | HISTORY:
28 | Created 2010.04.27 by Donovan Chandler
29 |
30 | EXAMPLE:
31 |
32 |
33 | ---------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------
/ListWithNull.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | rep_max = Count ( GetField ( relatedIDFieldName ) )
3 | ] ;
4 | Case (
5 | rep_max > 0 ;
6 | ListWithNullLoop ( relatedIDFieldName ; relatedValueFieldName ; nullPlaceholder ; 1 ; rep_max ; "" )
7 | )
8 | )
9 |
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | ListWithNull ( relatedIDFieldName ; relatedValueFieldName ; nullPlaceholder )
14 |
15 | PURPOSE:
16 | Returns list of related values, accounting for empty values.
17 | (FileMaker's native List function omits empty values.)
18 |
19 | EXAMPLES:
20 | ListWithNull (
21 | GetFieldName ( contact::id ) ;
22 | GetFieldName ( contact::name ) ;
23 | $_null
24 | )
25 | = "Fred¶¶Cindy" // where $_null = ""
26 | = "Fred¶¶Cindy" // where $_null = ""
27 |
28 | HISTORY:
29 | Created: 2011-Sep-29 09h50 PST — Donovan A. Chandler
30 | */
--------------------------------------------------------------------------------
/ListWithNullLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | value = GetNthRecord ( GetField ( relatedValueFieldName ) ; rep ) ;
3 | result = If ( IsEmpty ( value ) ; nullPlaceholder ; value ) ;
4 | resultFull = If ( rep = 1 ; result ; previousResults & ¶ & result )
5 | ] ;
6 | Case (
7 | rep < rep_max ;
8 | ListWithNullLoop ( relatedIDFieldName ; relatedValueFieldName ; nullPlaceholder ; rep + 1 ; rep_max ; resultFull ) ;
9 | resultFull
10 | )
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | ListWithNullLoop ( relatedIDFieldName ; relatedValueFieldName ; nullPlaceholder ; rep ; rep_max ; previousResults )
16 |
17 | PURPOSE:
18 | Performs recursion for ListWithNull ()
19 |
20 | NOTES:
21 | nullPlaceholder cannot contain only carriage returns.
22 |
23 | HISTORY:
24 | Created: 2011-Sep-29 09h50 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/LogDelimiter.calc:
--------------------------------------------------------------------------------
1 | "|"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: LogDelimiter
6 | PURPOSE: Stores delimiter used between audit log columns. Enables easy parsing of logs.
7 | HISTORY:
8 | Created: 2012-04-17 13:00 PST - Donovan Chandler
9 | Modified:
10 | */
--------------------------------------------------------------------------------
/LogExtract.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | labelDelim = "%" ;
3 | columnDelim = LogDelimiter ;
4 | row = GetValue ( logText ; 1 ) ;
5 | sFormatNode = Position ( format ; label ; 1 ; 1 ) ;
6 | index = PatternCount ( Left ( format ; sFormatNode ) ; labelDelim )
7 | ] ;
8 | TextBetween ( columnDelim & row & columnDelim ; columnDelim ; columnDelim ; index )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: LogExtract ( logText ; format ; label )
14 | PURPOSE: Extracts value from delimited text block according to where label resides in format.
15 | EXAMPLES:
16 | LogExtract ( "4/17/12|dchandler" ; "%Date%Account" ; "%Account" ) = "dchandler"
17 | HISTORY:
18 | Created: 2012-04-17 12:49 PST - Donovan Chandler
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/LogFormat.calc:
--------------------------------------------------------------------------------
1 | "%Date%Time%Account%Field%Before%After"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: LogFormat
6 | PURPOSE: Stores order of columns for audit logs. Enables easy parsing of logs.
7 | HISTORY:
8 | Created: 2012-04-17 13:00 PST - Donovan Chandler
9 | Modified:
10 | */
--------------------------------------------------------------------------------
/MVLSet.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_MVL[column] = valueListValues
3 | ] ;
4 | $$_MVL[column] ≠ "?" and not IsEmpty ( $$_MVL[column] )
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: MVLSetVar ( column ; valueListValues )
10 | PURPOSE: Sets values to global variable used for value lists using Magic Value List technique.
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2013-02-01 09:52 PT - Donovan Chandler
15 | Modified: 2013-02-14 11:53 PT - Donovan Chandler : returns 0 for empty or invalid value.
16 | */
--------------------------------------------------------------------------------
/MapRouteURL.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | points = listOfCoordinates ;
3 | remaining = TrimCR ( MiddleValues ( points ; 2 ; 999 ) ) ;
4 | daddr = Substitute ( remaining ; ¶ ; "+to:" )
5 | ] ;
6 | "http://maps.google.com/?"
7 | & "saddr=" & GetValue ( points ; 1 )
8 | & If ( NotEmpty ( remaining ) ; "&daddr=" & daddr )
9 | & "&output=embed"
10 | )
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | MapPointsURL ( listOfCoordinates )
15 |
16 | PURPOSE:
17 | Generates url for displaying group of waypoints on a Google map.
18 |
19 | EXAMPLES:
20 | MapPointsURL ( "37.3371,-122.0021¶37.3371,-122.0028" )
21 | = "http://maps.google.com/?q=37.3371,-122.0021&daddr=37.3371,-122.0028&output=embed"
22 |
23 | NOTES:
24 | URL syntax: http://mapki.com/wiki/Google_Map_Parameters
25 |
26 | HISTORY:
27 | Created: 2012-Mar-01 10h34 PST — Donovan A. Chandler
28 | */
--------------------------------------------------------------------------------
/MenuRevealIsOn.calc:
--------------------------------------------------------------------------------
1 | ListContains ( FOCUS::MENU_REVEALED_LIST ; menu )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | MenuRevealIsOn ( menu )
6 |
7 | PURPOSE:
8 | Returns True if specified menu is supposed to be revealed.
9 | You can hide menus and menu items in FMP 11 by setting the name to null. This function helps leverage that feature for items that are more often than note hidden.
10 |
11 | EXAMPLES:
12 |
13 |
14 | HISTORY:
15 | Created: 2011-Feb-18 11h35 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/MessageInvalidVar.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | objectString =
3 | Substitute (
4 | listOfObjects ;
5 | [ "&" ; "or" ] ;
6 | [ ¶ ; ", " ]
7 | )
8 | ];
9 | "Error: Missing Data" & ¶ &
10 | "Script: " & Get ( ScriptName ) & ¶ &
11 | "Objects: " & objectString
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | MessageInvalidVar ( listOfObjects )
17 |
18 | PURPOSE:
19 | Returns error message for list of objects that failed previous validation.
20 | Used to keep messages uniform and modifiable across solution.
21 |
22 | EXAMPLES:
23 | MessageInvalidVar ( "$_field & $_object" )
24 | = "The following objects are missing required data:¶$_field or $_object"
25 |
26 | HISTORY:
27 | Created: 2011-Jan-31 13h40 PST — Donovan A. Chandler
28 | */
--------------------------------------------------------------------------------
/NavLayoutRank.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | //layoutToMatch = "System List" ;
3 |
4 | ~navLayouts = FOCUS::NAV_LAYOUT_LIST_REP ;
5 | ~navRepMax = 8 ;
6 | ~navIndex = FieldRepMatch ( ~navLayouts ; layoutToMatch ; 1 ; ~navRepMax ) ;
7 |
8 | ~subnavLayouts = FOCUS::NAV_SUB_LAYOUT_LIST_REP ;
9 | ~subnavRepMax = 5 ;
10 | ~subnavIndex = FieldRepMatch ( ~subnavLayouts ; layoutToMatch ; 1 ; ~subnavRepMax )
11 | ] ;
12 | ~navIndex & If ( ~subnavIndex ; "." & ~subnavIndex )
13 | )
14 |
15 | /* __________________________________________________
16 |
17 | NAME: NavLayoutRank ( layoutToMatch )
18 | PURPOSE: Returns rank of current layout as specified in nav_layout record of active nav_set.
19 | EXAMPLES:
20 |
21 | HISTORY:
22 | Created: 2013-05-16 10:02 PT - Donovan Chandler
23 | Modified:
24 | */
--------------------------------------------------------------------------------
/NavViewLayout.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | /*
3 | rank = 2.1 ;
4 | targetView = "list" ;
5 | */
6 | ~rank = If ( not IsEmpty ( rank ) ; rank ; navLayoutrank ( Get ( LayoutName ) ) ) ;
7 | ~rankInt = Int ( ~rank ) ;
8 | ~layouts =
9 | Case (
10 | ~rankInt = ~rank ; FOCUS::NAV_LAYOUT_LIST_REP[ ~rank ] ;
11 | FOCUS::NAV_SUB_LAYOUT_LIST_REP[ ~rank ]
12 | )
13 | ] ;
14 | #IDValue ( ~layouts ; targetView )
15 | )
16 |
17 | /* __________________________________________________
18 |
19 | NAME: NavViewLayout ( rank ; targetView )
20 | PURPOSE: Returns layout corresponding to view for rank.
21 | If rank is empty, uses current layout's rank.
22 | EXAMPLES:
23 | NavViewLayout ( 2.1 ; "list" ) //= "Contact List"
24 | NavViewLayout ( 2.1 ; "table" ) //= "Contact Table"
25 | NavViewLayout ( "" ; "table" ) //= "Contact Table" where current layout has rank of 2.1
26 | HISTORY:
27 | Created: 2013-05-16 10:08 PT - Donovan Chandler
28 | Modified:
29 | */
--------------------------------------------------------------------------------
/NumberAsDollars.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | int = Int ( number ) ;
3 | dec = Abs ( number - int )
4 | ] ;
5 |
6 | If ( number < 0 ; "-" ) &
7 | "$" &
8 | TextInsertSeparator ( int ; "," ; 3 ) &
9 | If ( dec ≠ 0 ; Right ( dec ; 3 ) )
10 |
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | NumberAsDollars ( number )
16 |
17 | PURPOSE:
18 | Formats number or text string as dollar value.
19 |
20 | EXAMPLES:
21 | NumberAsDollars ( "5000.12" ) = "$5,000.12"
22 | NumberAsDollars ( "5000.1" ) = "$5,000.1"
23 | NumberAsDollars ( "5000" ) = "$5,000"
24 |
25 | HISTORY:
26 | Created: 2011-Jun-01 16h25 PST — Donovan Chandler based on function by Will Baker
27 | */
--------------------------------------------------------------------------------
/ParamAssign.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | names = VarAssignLoop ( Get ( ScriptParameter ) ; listOfParams ) ;
3 | error = If ( IsEmpty ( names ) ; 0 ; 10 )
4 | ] ;
5 | If (
6 | error ≠ 0 ;
7 | Let ( [
8 | count = ValueCount ( names ) ;
9 | str = Substitute ( names ; ¶ ; ", " ) ;
10 | msg = "Missing/invalid parameter" & If ( count > 1 ; "s" )
11 | & ": " & str ;
12 | v = VarSet ( "_invalid_params" ; names ; "t" ; False ) ;
13 | v = VarSet ( "_error_message" ; msg ; "t" ; False )
14 | ] ;
15 | ""
16 | )
17 | )
18 | & error
19 | )
20 |
21 | /* __________________________________________________
22 |
23 | NAME: ParamAssign ( listOfParams )
24 | PURPOSE: Instantiates named parameters, with optional type casting and validation.
25 | EXAMPLES: See ManParamAssign() for documentation.
26 | HISTORY:
27 | Created: 2012-03-16 09:15 PST - Donovan Chandler
28 | Modified:
29 | */
--------------------------------------------------------------------------------
/ParamValidate.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | not IsEmpty ( VarInvalid ( listOfVariableNames ) ) ;
3 | 10 ;
4 | 0
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | ParamValidate ( listOfVariableNames )
10 |
11 | PURPOSE:
12 | Returns 10 if parameters are invalid, else returns 0
13 |
14 | EXAMPLES:
15 | See subfunction, VarInvalid() for details.
16 |
17 | HISTORY:
18 | Created: 2010-Sep-07 08h51 PST — Donovan A. Chandler
19 | */
--------------------------------------------------------------------------------
/ParamValidateMessage.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | vars = VarInvalid ( listOfVariables ; 1 ) ;
3 | varsPretty = Substitute ( vars ; ¶ ; ", " )
4 | ] ;
5 | Case (
6 | ValueCount ( vars ) ;
7 | "Internal Error: Invalid parameters" & ¶ &
8 | ¶ &
9 | "Script: " & Get ( ScriptName ) & ¶ &
10 | "Missing Parameters: " & varsPretty
11 | )
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | ParamValidateMessage ( listOfVariables )
17 |
18 | PURPOSE:
19 | Returns dialog error message for missing parameters
20 |
21 | EXAMPLES:
22 |
23 |
24 | HISTORY:
25 | Created: 2010-Nov-08 11h48 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/PathDir.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | len = Length ( path ) ;
3 | pos = Position ( path ; "/" ; len ; -1 )
4 | ] ;
5 | Left ( path ; pos )
6 | )
7 |
8 | /* __________________________________________________
9 |
10 | NAME: PathDir ( path )
11 | PURPOSE: Strips file name from path.
12 | EXAMPLES:
13 | PathDir ( "filemac:/HD/Users/Shared/text.xml" )
14 | = "filemac:/HD/Users/Shared/"
15 | HISTORY:
16 | Created: 2012-02-03 22:00 PST - Donovan A. Chandler
17 | */
--------------------------------------------------------------------------------
/PathFileName.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | dirList = Substitute ( path ; "/" ; ¶ ) ;
3 | count = ValueCount ( dirList ) ;
4 | file = GetValue ( dirList ; count )
5 | ] ;
6 | Case (
7 | IsEmpty ( file ) ;
8 | GetValue ( dirList ; count - 1 ) ;
9 | file
10 | )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: PathFileName ( path )
16 | PURPOSE: Returns name of file referenced in path
17 | EXAMPLES:
18 | PathFileName ( "dir/fileName.txt/" ) = "fileName.txt"
19 | HISTORY:
20 | Created: 2011-10-06 13:09 PST - Donovan A. Chandler
21 | */
--------------------------------------------------------------------------------
/PathForAppleScript.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | pathList = Substitute ( posixPath ; ":/" ; ¶ ) ;
3 | path = GetValue ( pathList ; ValueCount ( pathList ) )
4 | ];
5 | Substitute ( path ; "/" ; ":" )
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | FilePathForAppleScript ( posixPath )
11 |
12 | PURPOSE:
13 | Converts POSIX path into an AppleScript file reference.
14 | This is to avoid converting the POSIX path to a valid file reference in AppleScript, which I was having trouble with.
15 |
16 | EXAMPLES:
17 |
18 |
19 | HISTORY:
20 | Created: 2011-Apr-29 18h13 PST — Donovan A. Chandler
21 | */
--------------------------------------------------------------------------------
/PathForFMP.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | path = GetValue ( pathList ; 1 ) ;
3 | pathCount = ValueCount ( pathList ) ;
4 | hdName = Get ( SystemDrive ) ;
5 |
6 | //-- Add disk name
7 | pathNew =
8 | If (
9 | Position ( "/" & path & "/" ; hdName ; 1 ; 1 ) = 0 ;
10 | hdName & TextStripLeft ( path ; "/" ) ;
11 | path
12 | ) ;
13 |
14 | //-- Undo shell escapes
15 | pathNew =
16 | Substitute ( pathNew ;
17 | [ "\ " ; " " ]
18 | )
19 | ];
20 | List (
21 | If ( not IsEmpty ( pathNew ) ; pathNew ) ;
22 | If ( pathCount > 1 ;
23 | FilePathForFMP ( RightValues ( pathList ; pathCount - 1 ) )
24 | )
25 | )
26 | )
27 |
28 | /* —————————————————————————————— //
29 | NAME:
30 | FilePathForFMP ( pathList )
31 |
32 | PURPOSE:
33 | Returns path usable in FileMaker.
34 | Adds system drive to shell paths.
35 |
36 | EXAMPLES:
37 | FilePathForShell ( "/Library/FileMaker\ Server/Data" )
38 | = "HD/Library/FileMaker Server/Data"
39 |
40 | HISTORY:
41 | Created: 2011-Nov-04 14h28 PST — Donovan Chandler
42 | */
--------------------------------------------------------------------------------
/PathFromHome.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | //-- Remove prefixes
3 | posColon = Position ( path ; ":" ; 1 ; 1 ) ;
4 | path = If ( posColon = 0 ; path ; Middle ( path ; posColon + 1 ; 999 ) ) ;
5 | path = If ( Left ( path ; 1 ) ≠ "/" ; path ; Middle ( path ; 2 ; 999 ) ) ;
6 |
7 | //-- Remove disk name
8 | hdName =
9 | GetValue (
10 | Substitute ( Get ( DesktopPath ) ; "/" ; ¶ ) ;
11 | 2
12 | ) ;
13 | hdNameLen = Length ( hdName ) ;
14 | path =
15 | If (
16 | Left ( path ; hdNameLen + 1 ) = hdName & "/" ;
17 | Middle ( path ; hdNameLen + 2 ; 999 ) ;
18 | path
19 | )
20 | ];
21 | path
22 | )
23 |
24 | /* —————————————————————————————— //
25 | NAME:
26 | FilePathFromHome ( path )
27 |
28 | PURPOSE:
29 | Removes prefix and hard drive name from path
30 |
31 | EXAMPLES:
32 | FilePathFromHome ( "filemac:/HD/Users/Donovan/Desktop" )
33 | = "Users/Donovan/Desktop"
34 |
35 | HISTORY:
36 | Created: 2011-Jun-29 15h39 PST — Donovan A. Chandler
37 | */
--------------------------------------------------------------------------------
/PathPosix.calc:
--------------------------------------------------------------------------------
1 | If (
2 | Abs ( Get ( SystemPlatform ) ) = 1 ; PathStripDisk ( path ) ;
3 | PathStripPrefix ( path )
4 | )
5 |
6 | /*
7 | Let([
8 |
9 | //-- Remove prefixes
10 | posColon = Position ( path ; ":" ; 1 ; 1 ) ;
11 | path = If ( posColon = 0 ; path ; Middle ( path ; posColon + 1 ; 999 ) ) ;
12 | path = If ( Left ( path ; 1 ) ≠ "/" ; "/" ) & path ;
13 |
14 | //-- Remove name of system drive
15 | disk = Get ( SystemDrive ) ;
16 | posDrive = Position ( path ; disk ; 1 ; 1 ) ;
17 | path =
18 | If (
19 | posDrive = 0 ; path ;
20 | Middle ( path ; Position ( path ; "/" ; posDrive + 1 ; 1 ) ; 999 )
21 | )
22 | ] ;
23 | Case (
24 | IsEmpty ( path ) ;
25 | "" ;
26 | path
27 | )
28 | )
29 | */
30 |
31 | /* __________________________________________________
32 |
33 | NAME: PathPosix ( path )
34 | PURPOSE: Converts path to POSIX style for use in plug-ins, etc.
35 | EXAMPLES:
36 | PathPosix ( "/Macintosh HD/Users/Admin/Desktop/text.txt" )
37 | // (Mac OS) = "/Macintosh HD/Users/Admin/Desktop/text.txt"
38 | // (Windows) = "C:/Users/Admin/Desktop/text.txt"
39 | HISTORY:
40 | Created: 2010-03-27 14:30 PT - Donovan Chandler
41 | Modified: 2013-01-24 12:46 PT - Donovan Chandler
42 | */
--------------------------------------------------------------------------------
/PositionIgnoring.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | char1 = Middle ( text ; start ; 1 )
3 | ] ;
4 | Case (
5 | Position ( charactersToIgnore ; char1 ; 1 ; 1 ) = 0 ;
6 | start ;
7 | PositionIgnoring ( text ; charactersToIgnore ; start + 1 )
8 | )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: PositionIgnoring ( text ; charactersToIgnore ; start )
14 | PURPOSE: Returns position of first character not included in charactersToIgnore.
15 | EXAMPLES:
16 | PositionIgnoring ( "123Dog" ; "D321 " ; 1 ) = 5
17 | HISTORY:
18 | Created: 2012-02-13 13:00 PT - Will M. Baker
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/PositionUnescaped.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | rep > repMax or start > Length ( text ) ; "" ;
3 | Let ( [
4 | Backslash = Char ( 92 ) ;
5 | rawStart = Position ( text ; character ; start ; 1 ) ;
6 | previousCharacter = If ( rawStart > 1 ; Middle ( text ; rawStart - 1 ; 1 ) ) ;
7 | isEscaped = ( previousCharacter = Backslash and rawStart ≠ Length ( text ) )
8 | ] ;
9 | Case (
10 | isEscaped ; PositionUnescaped ( text ; character ; rawStart + 1 ; repMax ; rep ) ;
11 | rawStart
12 | )
13 | )
14 | )
15 |
16 | /* __________________________________________________
17 |
18 | NAME: PositionUnescaped ( text ; character ; start ; repMax ; rep )
19 | PURPOSE: Finds position of first unescaped occurrence of character.
20 | EXAMPLES:
21 | Where $_text = "[ \[ \] ]"
22 | PositionUnescaped ( $_text ; 1 ; Length ( $_text ) ; 1 ) = 9
23 | HISTORY:
24 | Created: 2012-02-13 13:00 PT - Will M. Baker
25 | Modified: 2012-05-29 12:05 PT - Donovan Chandler : Added character param; more concise; renamed from #QuotePosition() to PositionUnescaped(); removed Backslash()
26 | Modified: 2012-10-17 11:40 PT - Donovan Chandler : Fixed final Case statement to return result.
27 | */
--------------------------------------------------------------------------------
/Project-Specific/AmountProratedForMonth.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | dte = GetAsDate ( dateOfAmount ) ;
3 | amount = amountSoFar ;
4 |
5 | month = Month ( dte ) ;
6 | yr = Year ( dte ) ;
7 | days_past = dte - Date ( month ; 1 ; yr ) + 1 ;
8 | days_ahead = Date ( month + 1 ; 0 ; yr ) - dte ;
9 | amount_daily = amount / days_past ;
10 | amount_prorated = amount + amount_daily * days_ahead
11 | ];
12 | amount_prorated
13 | )
14 |
15 | /* —————————————————————————————— //
16 | NAME:
17 | AmountProratedForMonth ( amountSoFar ; dateOfAmount )
18 |
19 | PURPOSE:
20 | Returns prorated amount for month
21 |
22 | EXAMPLES:
23 | AmountProratedForMonth ( 100 ; "2/14/10" ) = 200
24 |
25 | HISTORY:
26 | Created: 2010-Oct-11 12h09 PST — Donovan A. Chandler
27 | */
--------------------------------------------------------------------------------
/Project-Specific/CodeLabel.calc:
--------------------------------------------------------------------------------
1 | Case(
2 | linkOnly; "‡‡CODE_LINK[" & index & "]‡‡";
3 | "‡‡CODE[" & index & "]‡‡"
4 | )
5 |
6 | /* __________________________________________________
7 |
8 | NAME: CodeLabel ( index ; linkOnly )
9 | PURPOSE: Returns merge placeholder for LIBRARY_CODE record of specified index.
10 | EXAMPLES:
11 | //-- Merge value from LIBRARY_CODE::CODE
12 | CodeMergeLabel ( 1 ; False ) = "‡‡CODE[1]‡‡"
13 | //-- Merge value from LIBRARY_CODE::NAME
14 | CodeMergeLabel ( 1 ; True ) = "‡‡CODE_LINK[1]‡‡"
15 | HISTORY:
16 | Created: 2010-08-27 20:32 PST - Donovan A. Chandler
17 | */
18 |
--------------------------------------------------------------------------------
/Project-Specific/ConvertFieldContext.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _lis = Substitute( fieldName; "::"; ¶ );
3 | _table = GetValue( _lis; 1 );
4 | _table_num = contextNum - 1;
5 | _table_new = _table & "_OF_" & _table & "_" & _table_num
6 | ];
7 | _table_new & "::" & GetValue( _lis; 2 )
8 | )
9 |
10 | /* —————————————————————————————— //
11 | NAME:
12 | ConvertFieldContext( fieldName; contextNum )
13 |
14 | PURPOSE:
15 | Replaces name of table occurrence in fieldName to alternative TO.
16 | Applied when using GTRR to an alternative TO instead of opening a new window. (Preserves original context without the overhead of rendering a new window.)
17 |
18 | EXAMPLES:
19 | ConvertFieldContext (
20 | GetFieldName( CONTACT::NAME );
21 | 2
22 | ) = "CONTACT_OF_CONTACT_1::NAME"
23 |
24 | HISTORY:
25 | Created: 2010-Aug-23 13h34 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/Project-Specific/CriterionDecode.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | tag = TextBetween ( queryString ; "<" ; ">" ; 1 ) ;
3 | number = Filter ( tag ; "0123456789" ) ;
4 | merged =
5 | Case (
6 | Left ( tag ; 12 ) = "date-months:" ;
7 | DateMinusMonths ( Get ( CurrentDate ) ; number ) ;
8 | Left ( tag ; 4 ) = "date" ;
9 | Get ( CurrentDate ) ;
10 | tag = "account_name" ;
11 | Get ( AccountName )
12 | ) ;
13 | text = Substitute ( queryString ; "<" & tag & ">" ; merged )
14 | ] ;
15 | Case (
16 | PatternCount ( text ; "<" ) and PatternCount ( text ; ">" ) ;
17 | CriterionDecode ( Substitute ( text ; tag ; merged ) ) ;
18 | text
19 | )
20 | )
21 |
22 | /* —————————————————————————————— //
23 | NAME:
24 | CriterionDecode ( queryString )
25 |
26 | PURPOSE:
27 | Translates merge tag into searchable string
28 |
29 | EXAMPLES:
30 | (Where today = "1/1/10" )
31 | CriterionDecode ( "" ) = "1/1/2008"
32 | CriterionDecode ( "6/1/10..." ) = "6/1/09...7/19/2011"
33 |
34 | HISTORY:
35 | Created: 2010-Sep-14 17h36 PST — Donovan A. Chandler
36 | */
--------------------------------------------------------------------------------
/Project-Specific/DatabaseModule.calc:
--------------------------------------------------------------------------------
1 |
2 | Let([
3 | _privilege = Get ( AccountPrivilegeSetName )
4 |
5 | ];
6 | Case (
7 | PatternCount ( _privilege ; "Lester" );
8 | "LESTER";
9 | PatternCount ( _privilege ; "Haas" );
10 | "HAAS"
11 | )
12 | )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | DatabaseModule ( )
17 |
18 | PURPOSE:
19 | Returns name of module corresponding to the active user role
20 |
21 | EXAMPLES:
22 | DatabaseModule ( ) = "LESTER"
23 |
24 | HISTORY:
25 | Created: 2010-Jul-12 11h44 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/Project-Specific/DateFromString.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | _string = dateAsString
3 | ] ;
4 | Case (
5 | Position ( _string ; "." ; 1 ; 1 )
6 | + Position ( _string ; "-" ; 1 ; 1 ) ;
7 | Let ( [
8 | _list = Substitute ( _string ;
9 | [ "." ; ¶ ] ;
10 | [ " " ; ¶ ] ;
11 | [ "-" ; ¶ ]
12 | )
13 | ] ;
14 | Date (
15 | GetValue ( _list ; 2 ) ;
16 | GetValue ( _list ; 3 ) ;
17 | GetValue ( _list ; 1 )
18 | )
19 | )
20 | )
21 | )
22 |
23 | /* —————————————————————————————— //
24 | NAME:
25 | DateFromString ( dateAsString )
26 |
27 | PURPOSE:
28 | Converts strings into FileMaker-recognized dates.
29 | Formats accepted: yyyy.mm.dd or yyyy-mm-dd
30 |
31 | EXAMPLES:
32 | DateFromString ( "2008.01.07 ( 1.5 ) " ) = 01/07/2008
33 |
34 | HISTORY:
35 | Created: 2010-Jul-21 12h48 PST — Donovan A. Chandler
36 | */
--------------------------------------------------------------------------------
/Project-Specific/EncodeForHTMLScript.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | br = ""
3 | ] ;
4 | Substitute (
5 | text ;
6 | [ Char ( 10 ) ; br ] ; // Line feed
7 | [ Char ( 11 ) ; br ] ; // Vertical tab
8 | [ Char ( 12 ) ; br ] ; // Form feed
9 | [ Char ( 13 ) ; br ] // Carriage return
10 | )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: EncodeForHTMLScript ( text )
16 | PURPOSE: Encodes block of text for use in "html . p" and related scripts.
17 | EXAMPLES:
18 |
19 | HISTORY:
20 | Created: 2012-09-06 16:26 PST - Donovan Chandler
21 | Modified:
22 | */
--------------------------------------------------------------------------------
/Project-Specific/FieldNameReadable.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | field_name_full = Substitute ( fieldName ; "::" ; ¶ ) ;
3 | field_name = GetValue ( field_name_full ; ValueCount ( field_name_full ) )
4 | ] ;
5 | Proper (
6 | Substitute (
7 | field_name ;
8 | [ "_FLAGGED" ; "‡FLAGGED" ] ;
9 | [ "_FLAG" ; "" ] ;
10 | [ "‡FLAGGED" ; "_FLAGGED" ] ;
11 | [ "ID_" ; "" ] ;
12 | [ "_CT" ; "" ] ;
13 | [ "_CN" ; "" ] ;
14 | [ "_AT" ; "" ] ;
15 | [ "_" ; " " ]
16 | )
17 | )
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | FieldNameReadable ( fieldName )
23 |
24 | PURPOSE:
25 |
26 |
27 | EXAMPLES:
28 | FieldNameReadable ( GetFieldName ( CONTACT::FIRST_NAME )) = "First Name"
29 |
30 | HISTORY:
31 | Created: 2011-Jan-12 14h12 PST — Donovan A. Chandler
32 | */
--------------------------------------------------------------------------------
/Project-Specific/FilePathForWebViewer.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | isMac = Abs ( Get ( SystemPlatform ) ) = 1 ;
3 | pathPlain = PathStripPrefix ( path ) ;
4 | prefix = "file://" & If ( isMac ; "/Volumes/" )
5 | ] ;
6 | prefix & pathPlain
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: PathForWebViewer ( path )
12 | PURPOSE: Encodes file path for use in web viewer.
13 | EXAMPLES:
14 |
15 | NOTES:
16 | On Mac, prepend with "file:///Volumes/"
17 | On Win, prepend with "file:///"
18 | HISTORY:
19 | Created: 2010-06-23 16:39 PT - Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/Project-Specific/FilterIsCustom.calc:
--------------------------------------------------------------------------------
1 | Left ( filterText ; 1 ) = "<" and
2 | Right ( filterText ; 1 ) = ">"
3 |
4 | /* —————————————————————————————— //
5 | NAME:
6 | FilterIsCustom ( filterText )
7 |
8 | PURPOSE:
9 | Returns True if filterText is a custom message intended for display rather than searching. Used when pre-defined sets of records are placed in a filter portal.
10 |
11 | EXAMPLES:
12 | FilterIsCustom ( "" ) = 1
13 | FilterIsCustom ( "Roger" ) = 0
14 |
15 | HISTORY:
16 | Created: 2010-Jul-19 14h19 PST — Donovan A. Chandler
17 | */
--------------------------------------------------------------------------------
/Project-Specific/FocusLocationTab.txt:
--------------------------------------------------------------------------------
1 | Case (
2 | locationType = "PHONE" ; "tab_phone_entry" ;
3 | locationType = "EMAIL" ; "tab_email_entry" ;
4 | locationType = "ADDRESS" ; "tab_address_entry" ;
5 | locationType = "WEBSITE" ; "tab_website_entry"
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | FocusLocationTab ( locationType )
11 |
12 | PURPOSE:
13 | Returns name of tab to display when record of designated locationType is focussed
14 |
15 | EXAMPLES:
16 | FocusLocationTab ( "PHONE" ) = "tab_phone_entry"
17 |
18 | HISTORY:
19 | Created: 2010-Jun-08 09h21 PST — Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/Project-Specific/GenerateRange.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | valPrev = GetValue ( start ; ValueCount ( start ) ) ;
3 | val = valPrev + interval ;
4 | weekEnd = WeekOfYear ( "12/31/" & Left ( valPrev ; 4 ) ) ;
5 | val =
6 | Case (
7 | type = "wom" ;
8 | If ( Right ( val ; 2 ) ≤ weekEnd ; val ; val + 100 - weekEnd ) ;
9 | val
10 | ) ;
11 | result = List ( start ; val )
12 | ] ;
13 | Case (
14 | val < end ;
15 | GenerateRange ( type ; result ; end ; interval ) ;
16 | result
17 | )
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | GenerateRange ( type ; start ; end ; interval )
23 |
24 | PURPOSE:
25 | Generates return-delimited list per logic of specified type.
26 |
27 | EXAMPLES:
28 | GenerateRange ( "wom" ; 200551 ; 200602 ; 1 )
29 | = "200551¶200552¶200601¶200602"
30 |
31 | HISTORY:
32 | Created: 2011-Oct-13 12h56 PST — Donovan A. Chandler
33 | */
--------------------------------------------------------------------------------
/Project-Specific/LogForField.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | incidentID =
3 | If (
4 | not IsEmpty ( incidentID ) ; incidentID ;
5 | INCIDENT__FOCUS::ID
6 | ) ;
7 | action =
8 | If (
9 | not IsEmpty ( action ) ; action ;
10 | "MODIFY"
11 | )
12 | ];
13 | # ( "ID_INCIDENT" ; incidentID ) &
14 | # ( "ACTION" ; action ) &
15 | # ( "FIELD_NAME" ; Get ( ActiveFieldName ) ) &
16 | # ( "VALUE" ; Get ( ActiveFieldContents ) ) &
17 | # ( "BOOLEAN" ; isBoolean ) &
18 | # ( "ID_CHILD" ; childID ) &
19 | # ( "CHILD_CODE" ; childCode )
20 | )
21 |
22 | /* —————————————————————————————— //
23 | NAME:
24 | ParamLogForRelatedField ( incidentID ; action ; isBoolean ; childID ; childCode )
25 |
26 | PURPOSE:
27 | Creates parameter for script that logs field modifications, etc.
28 |
29 | EXAMPLES:
30 | ParamLogForRelatedField ( )
31 |
32 | NOTES:
33 | action, childID and childCode are only required for related records
34 |
35 | HISTORY:
36 | Created: 2011-Jan-21 15h02 PST — Donovan A. Chandler
37 | */
--------------------------------------------------------------------------------
/Project-Specific/ParamLogForField.calc:
--------------------------------------------------------------------------------
1 | # ( "ID_INCIDENT" ;
2 | If (
3 | not IsEmpty ( incidentID ) ; incidentID ;
4 | INCIDENT__FOCUS::ID
5 | )
6 | ) &
7 | # ( "ACTION" ; "MODIFY" ) &
8 | # ( "FIELD_NAME" ; Get ( ActiveFieldName ) ) &
9 | # ( "VALUE" ; Get ( ActiveFieldContents ) ) &
10 | # ( "BOOLEAN" ; isBoolean )
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | ParamLogForField ( incidentID ; isBoolean )
15 |
16 | PURPOSE:
17 | Creates parameter for script that logs field modifications, etc.
18 |
19 | EXAMPLES:
20 | ParamLogForField ( )
21 |
22 | HISTORY:
23 | Created: 2011-Jan-21 15h02 PST — Donovan A. Chandler
24 | */
--------------------------------------------------------------------------------
/Project-Specific/ParamLogForRelatedField.calc:
--------------------------------------------------------------------------------
1 | # ( "ID_INCIDENT" ;
2 | If (
3 | not IsEmpty ( incidentID ) ; incidentID ;
4 | INCIDENT__FOCUS::ID
5 | )
6 | ) &
7 | # ( "ACTION" ; "MODIFY" ) &
8 | # ( "FIELD_NAME" ; Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName ) ) &
9 | # ( "VALUE" ; Get ( ActiveFieldContents ) ) &
10 | # ( "BOOLEAN" ; isBoolean ) &
11 | # ( "ID_CHILD" ; childID ) &
12 | # ( "CHILD_CODE" ; childCode )
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | ParamLogForField ( incidentID ; action ; childID ; childCode ; isBoolean )
17 |
18 | PURPOSE:
19 | Creates parameter for script that logs field modifications, etc.
20 |
21 | EXAMPLES:
22 | ParamLogForField ( )
23 |
24 | HISTORY:
25 | Created: 2011-Jan-21 15h02 PST — Donovan A. Chandler
26 | */
--------------------------------------------------------------------------------
/Project-Specific/ResourceData.calc:
--------------------------------------------------------------------------------
1 | Case(
2 | dataType = "text" ; FOCUS::LIBRARY_CODE_REP[index] ;
3 | dataType = "name" ; "FOCUS::LIBRARY_CODE_REP[" & index & "]"
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | ResourceData( index; dataType )
9 |
10 | PURPOSE:
11 | Returns specified data from RESOURCE record.
12 |
13 | EXAMPLES:
14 | Where RESOURCE record has index 1...
15 |
16 | ResourceData( 1; "text" ) returns record text
17 | ResourceData( 1; "name" ) = "FOCUS::LIBRARY_CODE_REP[1]"
18 |
19 | HISTORY:
20 | Created: 2010-Aug-24 12h12 PST — Donovan A. Chandler
21 | */
--------------------------------------------------------------------------------
/Project-Specific/ResourceInclude.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | language = FOCUS::LIBRARY_LANGUAGE_REP[index] ;
3 | text = Case ( not urlOnly ; FOCUS::LIBRARY_CODE_REP[index] ) ;
4 | url = text //Case ( urlOnly ; FOCUS::LIBRARY_URL_REP[index] )
5 | ] ;
6 | Case (
7 | language = "CSS" ;
8 | Case (
9 | urlOnly ;
10 | "" ;
11 | ""
12 | ) ;
13 | language = "JavaScript" ;
14 | Case (
15 | urlOnly ;
16 | "" ;
17 | ""
18 | )
19 | )
20 | )
21 |
22 | /* —————————————————————————————— //
23 | NAME:
24 | ResourceInclude ( index ; urlOnly )
25 |
26 | PURPOSE:
27 | Wraps text or url from Resource record with specified index in HTML include statement.
28 |
29 | EXAMPLES:
30 |
31 |
32 | DEPENDENCIES:
33 | Custom Functions: PathEncodeForWebViewer ( )
34 | Fields: FOCUS fields that store RESOURCE data
35 |
36 | HISTORY:
37 | Created: 2010-Aug-28 16h24 PST — Donovan A. Chandler
38 | */
--------------------------------------------------------------------------------
/Project-Specific/ScriptTriggersAreOff.calc:
--------------------------------------------------------------------------------
1 | $$_script_triggers_disabled
2 |
3 | /* __________________________________________________
4 |
5 | NAME: ScriptTriggersAreOff ( )
6 | PURPOSE: Returns True if script triggers are being suppressed.
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2010-11-23 09:20 PST - Donovan A. Chandler
11 | */
12 |
--------------------------------------------------------------------------------
/Project-Specific/ScriptTriggersOff.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | $$_script_triggers_disabled = 1
3 | ];
4 | $$_script_triggers_disabled
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ScriptTriggersOff ( )
10 | PURPOSE: Sets boolean flag to True that prevents triggered scripts from executing.
11 | EXAMPLES:
12 | ScriptTriggersOff() = 1
13 | HISTORY:
14 | Created: 2010-11-23 09:20 PST - Donovan A. Chandler
15 | */
16 |
--------------------------------------------------------------------------------
/Project-Specific/ScriptTriggersOn.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | $$_script_triggers_disabled = ""
3 | ];
4 | $$_script_triggers_disabled
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ScriptTriggersOn ( )
10 | PURPOSE: Sets boolean flag to False, allowing triggered scripts to execute.
11 | EXAMPLES:
12 | ScriptTriggersOn()
13 | HISTORY:
14 | Created: 2010-11-23 09:20 PST - Donovan A. Chandler
15 | */
16 |
--------------------------------------------------------------------------------
/Project-Specific/TemplateMerge.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | isHot = GetAsBoolean ( CAR_CONTENT::Hot_Flag ) ;
3 | comment = If ( not IsEmpty ( $_template_comment ) ; $_template_comment ; "N/A" )
4 | ];
5 | Substitute ( text ;
6 | [ "::CAR_ProjectNo::" ; CAR_CONTENT::ProjectNo_ct ] ;
7 | [ "::CAR_ProjectNoAndCO::" ; CAR_CONTENT::ProjectNoDisplay_ct ] ;
8 | [ "::CAR_ProjectName::" ; CAR_CONTENT::ProjectName_ct ] ;
9 | [ "::CAR_ProjectManager::" ; CAR::ProjectMgr_ct ] ;
10 | [ "::Comment::" ; comment ] ;
11 | [ ":: (HOT!)::" ; If ( isHot ; " (HOT!)" ) ] ;
12 | [ "::ExpeditedMessage::" ; If ( isHot ; " Your immediate response is requested." ) ]
13 | )
14 | )
15 |
16 | /* —————————————————————————————— //
17 | NAME:
18 | TemplateMerge ( text )
19 |
20 | PURPOSE:
21 | Replaces labels in text with field values.
22 |
23 | EXAMPLES:
24 | Where CAR::ProjectMgr_ct = "Bill Banks"
25 |
26 | TemplateMerge ( "Dear ::CAR_ProjectManager::" )
27 | = "Dear Bill Banks"
28 |
29 | HISTORY:
30 | Created: 2011-Feb-25 10h47 PST — Donovan A. Chandler
31 | */
--------------------------------------------------------------------------------
/Project-Specific/TimeIncrement.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | max = GetAsTime ( maxTime )
3 | ; max = If ( max = "?" or IsEmpty ( max ) ; GetAsTime ( "24:00:00" ) ; max )
4 | ; new = GetAsTime ( startTime ) + incrementSeconds
5 | ; new = If ( new > max ; max ; new )
6 | ; new = RightWords ( GetAsTimestamp ( new ) ; 2 )
7 | ; hour = Hour ( new )
8 | ] ;
9 | If ( hour < 10 ; 0 )
10 | & new
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | TimeIncrement ( startTime ; incrementSeconds ; maxTime )
16 |
17 | PURPOSE:
18 | Returns time + provided seconds in AM/PM format.
19 |
20 | EXAMPLES:
21 | TimeIncrememt ( "7:15 AM" ; 2*60*60 ; "8:00 PM" ) //= "09:15 AM"
22 |
23 | HISTORY:
24 | Created: 2012-Feb-24 14h42 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/Project-Specific/TooltipQueryTips.calc:
--------------------------------------------------------------------------------
1 | "Special characters to use in your search:¶
2 | ¶
3 | ... range (\"1/1/2011...2/1/2011\")¶
4 | // today's date (\"1/1/2010...//\")¶
5 | @ any one character¶
6 | # any one digit (number)¶
7 | * zero or more characters¶
8 | \ escape next character (to match a special char literally)¶
9 | \"\" match phrase (from word start)¶
10 | *\"\" match phrase (from anywhere)¶
11 | ¶
12 | today minus N months"
13 |
14 | /* —————————————————————————————— //
15 | NAME:
16 | TooltipQueryTips
17 |
18 | PURPOSE:
19 | Stores text describing tips for for building queries.
20 |
21 | HISTORY:
22 | Created: 2011-Apr-22 15h12 PST — Donovan A. Chandler
23 | */
--------------------------------------------------------------------------------
/Project-Specific/text.getBetweenAll.calc:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | NAME:
3 | text.getBetweenAll ( text; from; to )
4 |
5 | PURPOSE:
6 | Returns return-delimited list of all text strings between 'from' and 'to' in 'text'
7 |
8 | HISTORY:
9 | Created 2010.04.20 by Donovan Chandler
10 |
11 | ---------------------------------------------------------------------------------------*/
12 |
13 | Let([
14 | _occurrenceCount = PatternCount ( text ; from );
15 |
16 | _rep = $$_text.getBetween_rep + 1;
17 | $$_text.getBetween_rep = _rep;
18 |
19 | _textBetween = text.getBetween ( text; from; to; _rep );
20 |
21 | _resultList = $$_text.getBetween_result;
22 | $$_text.getBetween_result =
23 | If ( not IsEmpty ( _resultList ); _resultList & ¶ )
24 | & _textBetween
25 | ];
26 | Case (
27 | //-- Continue
28 | _rep < _occurrenceCount;
29 | text.getBetweenAll ( text; from; to );
30 |
31 | //-- Return result
32 | _resultList
33 | & Let([ $$_text.getBetween_result = ""
34 | ; $$_text.getBetween_rep = ""
35 | ]; "" )
36 | )
37 |
38 | )
--------------------------------------------------------------------------------
/Project-Specific/time.getMicro.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | accuracy = 2 ; TimeMillis / 1000 ;
3 | TimeNano / 1000000000
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | time.getMicro ( accuracy )
9 |
10 | PURPOSE:
11 | Returns time in milliseconds or nanoseconds but with the decimal moved so that it can be calculated as seconds.
12 |
13 | EXAMPLES:
14 | time.getMicro ( "" ) = 1276879058.526657
15 | time.getMicro ( 2 ) = 1276879058.529
16 |
17 | HISTORY:
18 | Created: 2010-Jun-17 20h54 PST — Donovan A. Chandler
19 |
20 | DEPENDECIES:
21 | Uses external function created with ScriptMaster plug-in by 360Works.
22 |
23 | To create these functions:
24 | 1. Register the ScriptMaster plug-in. Download their plug-in for more details.
25 | 2. Set variables to the following calculations:
26 |
27 | RegisterGroovy( "TimeMillis" ; "System.currentTimeMillis()" )
28 |
29 | RegisterGroovy( "TimeNano" ; "System.nanoTime()" )
30 | */
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DonovanChan/fmfunctions/7917c203b8c51c7ff00f94d6036ea36f117d5e2a/README
--------------------------------------------------------------------------------
/RGBToCSS.calc:
--------------------------------------------------------------------------------
1 | Substitute (
2 | TrimAll ( RGBString ; True ; 3 ) ;
3 | ";" ;
4 | ","
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | RGBToCSS ( RGBString )
10 |
11 | PURPOSE:
12 | Converts RGB statement to CSS format
13 |
14 | EXAMPLES:
15 | RGBToCSS ( "RGB ( 255 ; 0 ; 0 )" )
16 | = "rgb(255;0;0)"
17 |
18 | HISTORY:
19 | Created: 2011-Apr-29 10h23 PST — Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/RGBToHex.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | Hex = "0123456789ABCDEF" ;
3 | RedHex =
4 | Middle ( Hex ; ( R - Mod ( R ; 16 ) ) / 16 + 1 ; 1 )
5 | & Middle ( Hex ; Mod ( R ; 16 ) + 1 ; 1 ) ;
6 | GreenHex =
7 | Middle ( Hex ; ( G - Mod ( G ; 16 ) ) / 16 + 1 ; 1 )
8 | & Middle ( Hex ; Mod ( G ; 16 ) + 1 ; 1 ) ;
9 | BlueHex = Middle ( Hex ; ( B - Mod ( B ; 16 ) ) / 16 + 1 ; 1 ) & Middle ( Hex ; Mod ( B ; 16 ) + 1 ; 1 )
10 | ] ;
11 | RedHex & GreenHex & BlueHex
12 | )
13 |
14 | /* __________________________________________________
15 |
16 | NAME: RGBToHex ( R ; G ; B )
17 | PURPOSE: Converts RGB values to Hex.
18 | EXAMPLES:
19 | RGBToHex ( 255 ; 255 ; 255 ) = "FFFFFF"
20 | HISTORY:
21 | Created: Daniel Wood, Digital Fusion Ltd
22 | Modified: 2011-09-12 19:00 PST - Donovan Chandler ; formatting
23 | */
24 |
--------------------------------------------------------------------------------
/SQLDate.calc:
--------------------------------------------------------------------------------
1 | "CAST( " &
2 | mFMb_DoSQL_Quote( Year( fmDateString ) & "-" & Month( fmDateString ) & "-" & Day( fmDateString) ) &
3 | " AS DATE )"
4 |
5 | /* —————————————————————————————— //
6 | NAME:
7 | SQLDate( fmDateStringString )
8 |
9 | PURPOSE:
10 | Returns SQL expression that converts a FileMaker date to SQL format.
11 |
12 | EXAMPLES:
13 | SQLDate( "1/5/2010" ) = "CAST( '2010-1-5' AS DATE )"
14 |
15 | HISTORY:
16 | Created: 2010-Sep-09 19h58 PST — Donovan A. Chandler
17 | */
--------------------------------------------------------------------------------
/SQLDebug.calc:
--------------------------------------------------------------------------------
1 | If (
2 |
3 | // The sql call results in an error, return empty so Data Viewer displays eror message
4 | sqlExecuted = "?" ; "" ;
5 |
6 | // The sql call is executed correctly, just return the result
7 | sqlExecuted
8 | )
9 |
10 | /* __________________________________________________
11 |
12 | NAME: SQLDebug ( sqlExecuted )
13 | PURPOSE: Allows you to view error message from ExecuteSQL( ) when performed in Data Viewer.
14 | EXAMPLES:
15 | SQLDebug ( ExecuteSQL ( "SELECT unexistingfield from table" ; "" ; "" ) )
16 | //= "The column named "unexistingfield" does not exist in any table in the column reference's scope."
17 | HISTORY:
18 | Created: Adapted from Andries Heylen (http://www.fmfunctions.com/mid/57)
19 | Modified: 2012-07-31 07:23 PST - Donovan Chandler
20 | */
--------------------------------------------------------------------------------
/SQLFieldSeparator.calc:
--------------------------------------------------------------------------------
1 | "|"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: SQLFieldSeparator ( )
6 | PURPOSE: Global storage of separator used between columns/fields returned from SQL queries.
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2012-03-13 11:20 PST - Donovan Chandler
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/SQLFunctions.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DonovanChan/fmfunctions/7917c203b8c51c7ff00f94d6036ea36f117d5e2a/SQLFunctions.zip
--------------------------------------------------------------------------------
/SQLResponse.calc:
--------------------------------------------------------------------------------
1 | ArrayCell (
2 | array ;
3 | columnIndex ;
4 | SQLFieldSeparator ;
5 | rowIndex ;
6 | SQLRowSeparator
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: SQLResponse ( array ; columnIndex ; rowIndex )
12 | PURPOSE: Returns value from SQL response.
13 | Used when array of columns is returned.
14 | EXAMPLES:
15 | $_array = ExecuteSQL ( "SELECT city, state FROM table" ; "|" ; "¶" )
16 | //= "Oakland|CA¶Portland|OR"
17 |
18 | SQLResponse ( $_array ; 2 ; 2 ) //= "OR"
19 | HISTORY:
20 | Created: 2012-05-25 10:49 PST - Donovan Chandler
21 | Modified:
22 | */
--------------------------------------------------------------------------------
/SQLRowSeparator.calc:
--------------------------------------------------------------------------------
1 | "¶"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: SQLRowSeparator ( )
6 | PURPOSE: Global storage of separator used between rows returned from SQL queries.
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2012-03-13 11:20 PST - Donovan Chandler
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/SQLString.calc:
--------------------------------------------------------------------------------
1 | "'" & Substitute ( text ; "'" ; "''" ) & "'"
2 |
3 | /* __________________________________________________
4 |
5 | WARNING: Function may be hardcoded into SqList ( )
6 |
7 | NAME: SqString ( text )
8 | PURPOSE: Quotes string for use in SQL
9 | EXAMPLES:
10 | SQLQuote ( "contact" ) = 'contact'
11 | NOTES:
12 | For escaping of reserved characters like "'" or "%",
13 | Use the optional arguments parameter in ExecuteSql( )
14 | HISTORY:
15 | Created: 2012-03-28 11:11 PT - Donovan Chandler
16 | Modified:
17 | */
--------------------------------------------------------------------------------
/SQLTable.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | fieldName = GetFieldName ( field ) ;
3 | fieldName = If ( fieldName = "?" ; field ; fieldName ) ;
4 | table = Left ( fieldName ; Position ( fieldName ; "::" ; 1 ; 1 ) - 1 )
5 | ];
6 | "\"" & Lower ( table ) & "\""
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: SQLTable ( field )
12 | PURPOSE: Returns name of field's basetable for use in SQL statements.
13 | EXAMPLES:
14 | SQLTable ( CONTACT::Name ) = "contact"
15 | SQLTable ( GetFieldName ( CONTACT::Name ) ) = "contact"
16 | HISTORY:
17 | Created: 2011-11-04 16:45 PT - Donovan Chandler
18 | Modified: 2012-11-20 17:43 PT - Donovan Chandler : Quotes in case of reserved word.
19 | */
--------------------------------------------------------------------------------
/ScriptMasterDependent/HTMLGetCellRight.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | pattern =
3 | ">" & cellValueToLeft & "<" // Label
4 | & ".+?" // Open cell to right
5 | & "(?:.*?>)?" // Skip inner tags
6 | & "(.*?)" // Capture
7 | & "<.*?" // Close cell to right
8 | ; value = FilterRegex( html ; pattern ; 1 )
9 | ] ;
10 | Case (
11 | value = "ERROR" ; "" ;
12 | LeftWords ( value ; 9999 )
13 | )
14 | )
15 |
16 | /* —————————————————————————————— //
17 | NAME:
18 | HTMLGetCellRight ( html ; cellValueToLeft )
19 |
20 | PURPOSE:
21 | Retrieves text of element to right of element containing specified value.
22 |
23 | EXAMPLES:
24 |
25 |
26 | HISTORY:
27 | Created: 2011-Aug-18 09h34 PST — Donovan A. Chandler
28 | */
--------------------------------------------------------------------------------
/ScriptMasterDependent/HTMLGetRow.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | row = FilterRegex ( text ; "( | )" ; occurrence )
3 | ];
4 | Case (
5 | row = "ERROR" ; "" ;
6 | row
7 | )
8 | )
9 |
10 | /* —————————————————————————————— //
11 | NAME:
12 | HTMLGetRow ( text ; rowMatch ; occurrence )
13 |
14 | PURPOSE:
15 | Returns nth row that matches rowMatch expression (regex).
16 | Leave occurrence parameter blank to receive all matching rows.
17 |
18 | EXAMPLES:
19 | HTMLGetRow (
20 | "
21 | Dog | Rufus | 7yrs |
22 | Cat | Susie | 9yrs |
23 |
" ;
24 | ">Rufus<" ;
25 | 1
26 | ) = "Dog | Rufus | 7yrs |
"
27 |
28 | HISTORY:
29 | Created: 2011-Aug-26 13h54 PST — Donovan Chandler
30 | */
--------------------------------------------------------------------------------
/ScriptMasterDependent/HTMLGetRowCell.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | row = FilterRegex ( text ; "()" ; 1 ) ;
3 | cell = FilterRegex ( row ; "(?:(.*?)<" ; 1 )
4 | ];
5 | Case (
6 | cell = "ERROR" ; "" ;
7 | LeftWords ( cell ; 9999 )
8 | )
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | HTMLGetRowCell ( text ; rowMatch ; columnNum )
14 |
15 | PURPOSE:
16 | Returns innermost text value of nth column in matched row.
17 | Also trims leading and trailing whitespace.
18 |
19 | EXAMPLES:
20 | HTMLGetRowCell (
21 | "Dog | Rufus | 7yrs |
" ;
22 | ">Rufus<" ;
23 | 1
24 | ) = "Dog"
25 |
26 | HTMLGetRowCell (
27 | "Dog | Rufus | 7yrs |
" ;
28 | "" ;
29 | 1
30 | ) = "Dog"
31 |
32 | HISTORY:
33 | Created: 2011-Aug-23 12h55 PST — Donovan A. Chandler
34 | */
--------------------------------------------------------------------------------
/ScriptTraceAdd.calc:
--------------------------------------------------------------------------------
1 | TraceAdd (
2 | Get ( ScriptName ) ;
3 | "Script" ;
4 | action ;
5 | note
6 | )
7 |
8 | /* __________________________________________________
9 |
10 | NAME: ScriptTraceAdd ( action ; note )
11 | PURPOSE: Appends new entry to trace stack. Used for monitoring script performance.
12 | EXAMPLES:
13 | ScriptTraceAdd ( "debug" ; "Finished sort operation" )
14 | NOTES:
15 | Valid action values: {start, end, debug, error}
16 | HISTORY:
17 | Created: 2011-04-26 14:58 PT - Donovan Chandler
18 | */
--------------------------------------------------------------------------------
/ScriptTraceIsOn.calc:
--------------------------------------------------------------------------------
1 | GetAsBoolean ( $$_trace_enabled )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: ScriptTraceIsOn ( )
6 | PURPOSE: Returns "1" (True) if scripts are permitted to build trace log.
7 | HISTORY:
8 | Created: 2012-04-11 11:27 PST - Donovan Chandler
9 | Modified:
10 | */
11 |
--------------------------------------------------------------------------------
/ScriptTraceOff.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_trace_enabled = False
3 | ] ;
4 | $$_trace_enabled
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ScriptTraceOff ( )
10 | PURPOSE: Sets global flag to ensure scripts are NOT permitted to build trace log.
11 | HISTORY:
12 | Created: 2012-04-11 11:27 PST - Donovan Chandler
13 | Modified:
14 | */
--------------------------------------------------------------------------------
/ScriptTraceOn.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_trace_enabled = True
3 | ] ;
4 | $$_trace_enabled
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: ScriptTraceOn ( )
10 | PURPOSE: Sets global flag to ensure scripts are permitted to build trace log.
11 | HISTORY:
12 | Created: 2012-04-11 11:27 PST - Donovan Chandler
13 | Modified:
14 | */
--------------------------------------------------------------------------------
/SecondsAsString.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | secTotal = GetAsNumber( theSeconds );
3 | sec = Mod( secTotal; 60 );
4 | minTotal = Int( secTotal / 60 );
5 | hour = Int( minTotal / 60 );
6 | min = Mod( minTotal; hour )
7 | ];
8 | Case(
9 | //-- Errors
10 | IsEmpty( secTotal ); "";
11 |
12 | //-- Custom formats
13 |
14 | //-- Default
15 | hour > 0; hour & " hr " & min & " min " & sec & " sec";
16 |
17 | minTotal & " min " & sec & " sec"
18 | )
19 | )
20 |
21 | /* —————————————————————————————— //
22 | NAME:
23 | SecondsAsString ( theSeconds; format )
24 |
25 | PURPOSE:
26 | Returns time value as readable string
27 |
28 | EXAMPLES:
29 | TimeAsString ( "10:25:44"; "" ) =
30 |
31 | HISTORY:
32 | Created: 2010-Sep-08 12h01 PST — Donovan A. Chandler
33 | */
--------------------------------------------------------------------------------
/SetIfEmpty.calc:
--------------------------------------------------------------------------------
1 | If ( IsEmpty ( existingValue ) ; newValue ; existingValue )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | SetIfEmpty ( existingValue ; newValue )
6 |
7 | PURPOSE:
8 | Analogous to "||=" assignment operator in Ruby.
9 | Replaces existingValue with newValue only if existingValue is empty.
10 |
11 | EXAMPLES:
12 | SetNotEmpty ( "" ; "fum" ) = "fum"
13 | SetNotEmpty ( "foo" ; "fum" ) = "foo"
14 |
15 | $_foo ||= "fum" // Ruby example
16 |
17 | HISTORY:
18 | Created: 2011-Aug-26 14h42 PST — Donovan A. Chandler
19 | */
--------------------------------------------------------------------------------
/SetNotEmpty.calc:
--------------------------------------------------------------------------------
1 | If ( IsEmpty ( newValue ) ; existingValue ; newValue )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | SetNotEmpty ( existingValue ; newValue )
6 |
7 | PURPOSE:
8 | Replaces existingValue with newValue only if newValue isn't empty.
9 |
10 | EXAMPLES:
11 | SetNotEmpty ( "" ; "fum" ) = "fum"
12 | SetNotEmpty ( "foo" ; "fum" ) = "fum"
13 |
14 | HISTORY:
15 | Created: 2011-Aug-26 14h42 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/SqFieldListLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | value = GetValue ( listOfFieldNames ; 1 ) ;
3 | valueNew = SqField ( value ) ;
4 | valueCnt = ValueCount ( listOfFieldNames )
5 | ] ;
6 | Case (
7 | valueCnt ≤ 1 ; valueNew ;
8 | List (
9 | valueNew ;
10 | SqFieldListLoop ( RightValues ( listOfFieldNames ; valueCnt - 1 ) )
11 | )
12 | )
13 | )
14 |
15 | /* __________________________________________________
16 |
17 | NAME: SqFieldListLoop ( listOfFieldNames )
18 | PURPOSE: Converts list of field names into SQL-escaped field references.
19 | EXAMPLES:
20 | SqFieldListLoop ( List (
21 | GetFieldName ( account::id_person ) ;
22 | GetFieldname ( ACCOUNT::PRIVILEGE_NAME_LT )
23 | ) ) = "\"account\".\"id_person\"¶\"account\".\"privilege_name_lt\""
24 | HISTORY:
25 | Created: 2013-02-18 12:18 PT - Donovan Chandler
26 | Modified:
27 | */
--------------------------------------------------------------------------------
/SqGetByID.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | query =
3 | "SELECT " & SqField ( targetField ) &
4 | "¶FROM " & SqTable ( targetField ) &
5 | "¶WHERE " & SqField ( idField ) & " = " & sqString ( idField )
6 | ] ;
7 | SQL ( query )
8 | )
9 |
10 | /* __________________________________________________
11 |
12 | NAME: SqGetByID ( targetField ; idField )
13 | PURPOSE: Retrieves value from record matching supplied id value.
14 | EXAMPLES:
15 |
16 | HISTORY:
17 | Created: 2013-01-25 14:01 PT - Donovan Chandler
18 | Modified:
19 | */
--------------------------------------------------------------------------------
/SqGetColumn.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | query =
3 | "SELECT DISTINCT" & SqField ( targetField ) &
4 | "¶FROM " & SqTable ( targetField )
5 | ] ;
6 | SQL ( query )
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: SqGetColumn ( targetField )
12 | PURPOSE: Retrieves all unique values from a column.
13 | EXAMPLES:
14 |
15 | HISTORY:
16 | Created: 2013-01-25 14:01 PT - Donovan Chandler
17 | Modified:
18 | */
--------------------------------------------------------------------------------
/SqGetFields.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | fields = Substitute ( targetSQLFields ; ¶ ; ", " ) ;
3 | query =
4 | "SELECT " & fields &
5 | "¶FROM " & SqTable ( matchField ) &
6 | "¶WHERE lower(" & SqField ( matchField ) & ") = " & Lower ( SqStringSmart ( matchValue ) )
7 | ] ;
8 | SQL ( query )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: SqGetFields ( targetSQLFields ; matchField ; matchValue )
14 | PURPOSE: Gets respective field values from record based on matching column value.
15 | EXAMPLES:
16 | SqGetFields (
17 | List ( SqField ( PERSON::NAME ) ; SqField ( PERSON::EMAIL ) ) ;
18 | PERSON::ID ;
19 | "PERSON-0035"
20 | ) = "Donovan Chandler††donovan_c@beezwax.net"
21 | // Assuming SQL( ) uses "††" as the column separator
22 | HISTORY:
23 | Created: 2013-01-31 10:01 PT - Donovan Chandler
24 | Modified: 2013-02-14 11:50 PT - Donovan Chandler : supports number is matchValue.
25 | Modified: 2013-02-21 10:44 PT - Donovan Chandler : uses lower() to loosen search.
26 | */
--------------------------------------------------------------------------------
/SqGetLike:
--------------------------------------------------------------------------------
1 | Let ( [
2 | query =
3 | "SELECT " & SqField ( targetField ) &
4 | "¶FROM " & SqTable ( targetField ) &
5 | "¶WHERE " & SqField ( matchField ) & " LIKE " & matchSQLValue
6 | ] ;
7 | SQL ( query )
8 | )
9 |
10 | /* __________________________________________________
11 |
12 | NAME: SqGetLike ( targetField ; matchField ; matchSQLValue )
13 | PURPOSE: Gets value from record based on matching column value. Similar to SqGet( ) except it uses the "LIKE" operator.
14 | EXAMPLES:
15 | SqGetLike (
16 | GetFieldName ( CONTACT::NAME ) ;
17 | GetFieldName ( CONTACT::NAME ) ;
18 | SqString ( "Do%" )
19 | ) = "Dorothy‡‡Donald" // where SqRowSeparator() = "‡‡"
20 | HISTORY:
21 | Created: 2013-02-28 15:06 PT - Donovan Chandler
22 | Modified:
23 | */
--------------------------------------------------------------------------------
/SqGetLiteral:
--------------------------------------------------------------------------------
1 | Let ( [
2 | matchIsNumber = ( Left ( matchSQLValue ; 1 ) ≠ "'" ) ;
3 | query =
4 | "SELECT " & SqField ( targetField ) &
5 | "¶FROM " & SqTable ( targetField ) &
6 | If (
7 | matchIsNumber ;
8 | "¶WHERE " & SqField ( matchField ) & " = " & matchSQLValue ;
9 | "¶WHERE " & SqField ( matchField ) & " = " & matchSQLValue
10 | )
11 | ] ;
12 | SQL ( query )
13 | )
14 |
15 | /* __________________________________________________
16 |
17 | NAME: SqGetLiteral ( targetField ; matchField ; matchSQLValue )
18 | PURPOSE: Gets value from record based on matching column value. Similar to SqGet( ) except it searches for an exact match against the matchSQLValue parameter without using lower() or any escaping.
19 | EXAMPLES:
20 | SqGetLiteral (
21 | GetFieldName ( CONTACT::NAME ) ;
22 | GetFieldName ( CONTACT::PHONE ) ;
23 | SqString ( "888.835.4483" )
24 | ) = "Beezwax" // where CONTACT::PHONE is a text field
25 | HISTORY:
26 | Created: 2013-02-28 10:27 PT - Donovan Chandler
27 | Modified:
28 | */
--------------------------------------------------------------------------------
/SqListLoop:
--------------------------------------------------------------------------------
1 | Let ( [
2 | raw = GetValue ( listToDelimit ; 1 ) ;
3 | quoted = SqString ( raw ) ;
4 | count = ValueCount ( listToDelimit )
5 | ] ;
6 | Case (
7 | count > 1 ;
8 | quoted & "," &
9 | SqListLoop ( RightValues ( listToDelimit ; count - 1 ) ) ;
10 | quoted
11 | )
12 | )
13 |
14 | /* __________________________________________________
15 |
16 | NAME: SqListLoop ( listToDelimit )
17 | PURPOSE: Performs recursion for SqList.
18 | EXAMPLES:
19 | SqListLoop ( "dog¶cat\¶mouse" ) = "'dog','cat¶mouse'"
20 | HISTORY:
21 | Created: 2011-10-26 16:23 PT - Donovan A. Chandler
22 | */
--------------------------------------------------------------------------------
/SqResponseAsDate.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | lst = Substitute ( listOfSQLDates ; [ "-" ; ¶ ] ; [ " " ; ¶ ] ; [ ":" ; ¶ ] ) ;
3 | yr = GetAsNumber ( GetValue ( lst ; 1 ) ) ;
4 | mnth = GetAsNumber ( GetValue ( lst ; 2 ) ) ;
5 | dy = GetAsNumber ( GetValue ( lst ; 3 ) ) ;
6 | valueCnt = ValueCount ( listOfSQLDates ) ;
7 | value =
8 | Case (
9 | IsEmpty ( lst ) ; "" ;
10 | Date ( mnth ; dy ; yr )
11 | )
12 | ] ;
13 | value
14 | & If ( valueCnt > 1 ;
15 | ¶ & SqResponseAsDate ( RightValues ( listOfSQLDates ; valueCnt - 1 ) )
16 | )
17 | )
18 |
19 | /* __________________________________________________
20 |
21 | NAME: SqResponseAsDate ( listOfSQLDates )
22 | PURPOSE: Converts one or more return-delimted SQL dates to FileMaker equivalent
23 | EXAMPLES / TESTS: List (
24 | SqResponseAsDate ( "2012-08-18" ) = "8/18/2012"
25 | ; SqResponseAsDate ( "2014-01-18¶2014-02-19" ) = "1/18/2014¶2/19/2014"
26 | )
27 | HISTORY:
28 | Created: 2012-08-18 11:18 PST - Hanzel Morato
29 | Modified: 2012-09-27 16:08 PST — Will M. Baker. Updated for TimeStamp.
30 | Modified: 2014-02-11 13:16 PT - Donovan Chandler. Recursive; changed name from SqDateConvertSqlToFileMaker().
31 | */
--------------------------------------------------------------------------------
/SqStringSmart.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | not IsEmpty ( textOrNumber ) and GetAsNumber ( textOrNumber ) = textOrNumber ; textOrNumber ;
3 | SqString ( textOrNumber )
4 | )
5 |
6 | /* __________________________________________________
7 |
8 | NAME: SqStringSmart ( textOrNumber )
9 | PURPOSE: Quotes string for use in SQL if it is a string.
10 | EXAMPLES:
11 | SqStringSmart ( "contact" ) = "'contact'"
12 | SqStringSmart ( "2.5" ) = "2.5"
13 | SqStringSmart ( "" ) = "''"
14 | NOTES:
15 | Use the optional arguments parameter in ExecuteSql( )
16 | if you want to be sure of proper handling of strings.
17 | HISTORY:
18 | Created: 2013-02-14 11:48 PT - Donovan Chandler
19 | Modified: 2013-10-11 14:19 PT - Donovan Chandler : accounts for empty values.
20 | */
--------------------------------------------------------------------------------
/StringRepeat.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | repetitions ≤ 0 ; "" ;
3 | repetitions = 1 ; string ;
4 | string & StringRepeat ( string ; repetitions - 1 )
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: StringRepeat ( string ; repetitions )
10 | PURPOSE: Repeats string n times
11 | EXAMPLES:
12 | StringRepeat ( "-" ; 4 ) = "----"
13 | HISTORY:
14 | Created: 2011-02-02 16:23 PST - Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/StringRepeatLoop.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | repMax ≤ 0 ; "" ;
3 | rep ≥ repMax ; string ;
4 | string & StringRepeatLoop ( string ; rep + 1 ; repMax )
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: StringRepeatLoop ( string ; rep ; repMax )
10 | PURPOSE: Performs recursion for StringRepeat ()
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2011-02-02 16:26 PST - Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/StringToList.calc:
--------------------------------------------------------------------------------
1 | ListTrimValues (
2 | Substitute ( string ; delimiter ; ¶ )
3 | )
4 |
5 | /* —————————————————————————————— //
6 | NAME:
7 | StringToList ( string ; delimiter )
8 |
9 | PURPOSE:
10 | Converts string to list, breaking lines on delimiter.
11 | Removes spaces
12 |
13 | EXAMPLES:
14 | StringToList ( "dog ,cat, mouse" ; "," ) = "dog¶cat¶mouse"
15 |
16 | HISTORY:
17 | Created: 2011-Feb-02 11h53 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/SuperContainerViewRawTypes.calc:
--------------------------------------------------------------------------------
1 | List (
2 | "pdf" ;
3 | ""
4 | )
5 |
6 | /* —————————————————————————————— //
7 | NAME:
8 | SuperContainerViewRawTypes
9 |
10 | PURPOSE:
11 | Provides central list of all types of files to view in raw view.
12 |
13 | EXAMPLES:
14 |
15 |
16 | HISTORY:
17 | Created: 2011-May-13 13h32 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/TextAsBoolean.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | stringTrim = Trim( string );
3 | yes = "yes¶y¶1¶true";
4 | no = "no¶n¶0¶false"
5 | ];
6 | Case(
7 | //-- Null, convert if requested
8 | IsEmpty( stringTrim ) and nullAsFalse;
9 | 0;
10 |
11 | //-- True
12 | ValueCount( FilterValues( yes; stringTrim ) );
13 | 1;
14 |
15 | //-- False
16 | ValueCount( FilterValues( no; stringTrim ) );
17 | 0;
18 |
19 | //-- Unrecognized
20 | preserveUnrecognizedValues;
21 | string
22 | )
23 | )
24 |
25 | /* —————————————————————————————— //
26 | NAME:
27 | TextAsBoolean( string ; nullAsFalse ; preserveUnrecognizedValues )
28 |
29 | PURPOSE:
30 | Converts recognized strings into boolean values.
31 |
32 | EXAMPLES:
33 | TextAsBoolean( "yes"; 1; 1 ) = 1
34 | TextAsBoolean( "maybe"; 1; 1 ) = "maybe"
35 | TextAsBoolean( "maybe"; 1; 0 ) = ""
36 | TextAsBoolean( ""; 1; 1 ) = 0
37 | TextAsBoolean( ""; 0; 1 ) = ""
38 |
39 | HISTORY:
40 | Created: 2010-Sep-21 14h26 PST — Donovan A. Chandler
41 | */
--------------------------------------------------------------------------------
/TextBeginsWith.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | len = Length ( matchString )
3 | ] ;
4 | Left ( text ; len ) = matchString
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | TextBeginsWith ( text ; matchString )
10 |
11 | PURPOSE:
12 | Returns True if test begins with matchString
13 |
14 | EXAMPLES:
15 | TextBeginsWith ( "doggie" ; "Dog" ) // = True
16 | TextBeginsWith ( "doggie" ; "dot" ) // = False
17 |
18 | HISTORY:
19 | Created: 2012-Feb-02 10h36 PST — Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/TextCapitalizeFirstLetters.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~line = GetValue ( text ; startLineNumber ) ;
3 | ~firstWord = LeftWords ( ~line ; 1 ) ;
4 | ~firstWordStart = Position ( ~line ; ~firstWord ; 1 ; 1 ) ;
5 | ~firstWordNew = Upper ( Left ( ~firstWord ; 1 ) ) & Middle ( ~firstWord ; 2 ; 99 ) ;
6 | ~remainingText = Middle ( ~line ; ~firstWordStart + Length ( ~firstWord ) ; Length ( ~line ) )
7 | ] ;
8 |
9 | List (
10 | Left ( ~line ; ~firstWordStart - 1 ) & ~firstWordNew & ~remainingText ;
11 | If ( ValueCount ( text ) > startLineNumber ; FormatWorkItemCapitalization ( text ; startLineNumber + 1 ) )
12 | )
13 |
14 | )
15 |
16 | /* __________________________________________________
17 |
18 | NAME: TextCapitalizeFirstLetters ( text ; startLineNumber )
19 | PURPOSE: Capitalizes first letter of each line of text.
20 | Leaves leading symbols in tact.
21 | Leaves acronyms in tact.
22 | EXAMPLES:
23 | TextCapitalizeFirstLetters ( "the¶- red¶FOX" ; 1 )
24 | // Returns "The¶- Red¶FOX"
25 | HISTORY:
26 | Created: 2013-09-27 10:30 PT - Donovan Chandler
27 | Modified:
28 | */
--------------------------------------------------------------------------------
/TextCleanQuotes.calc:
--------------------------------------------------------------------------------
1 | Substitute ( text ;
[ Char ( 147 ) ; "\"" ] ; // left curly quote
[ Char ( 148 ) ; "\"" ] ; // right curly quote
[ Char ( 8220 ) ; "\"" ] ; // left curly quote
[ Char ( 8221 ) ; "\"" ] // right curly quote
)
/* __________________________________________________
NAME: TextCleanQuotes ( text )
PURPOSE: Replaces curly double and single quotes with regular double quotes.
EXAMPLES:
HISTORY:
Created: 2011-07-22 14:14 PT - Donovan Chandler
NOTES:
Code ( "
" ) = 32
Code ( "¶" ) = 13
*/
--------------------------------------------------------------------------------
/TextEncodeForAppleScript.calc:
--------------------------------------------------------------------------------
1 | "\"" & Substitute ( text ;
2 | [ "\\" ; "\\\\" ] ;
3 | [ " " ; "\t" ] ;
4 | [ "\"" ; "\\\"" ]
5 | ) & "\""
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TextEncodeForAppleScript ( text )
10 | PURPOSE: Escapes string literals for AppleScript
11 | EXAMPLES:
12 | TextEncodeForAppleScript ( "Quotation: \"hello\", Tab: , Backslash:\\" )
13 | = "\"Quotation: \\\"hello\\\", Tab:\t, Backslash:\\\\\""
14 | which reads in the data viewer as: "Quotation: \"hello\", Tab:\t, Backslash:\\"
15 | HISTORY:
16 | 2011-03-15 17:50 PDT - Donovan Chandler
17 | 2014-07-21 10:40 PDT - Donovan Chandler : Wrap result in quotation marks
18 | */
19 |
--------------------------------------------------------------------------------
/TextEncodeForFilePath.calc:
--------------------------------------------------------------------------------
1 | Substitute (
2 | text ;
3 | [ ¶ ; " " ] ;
4 | [ "|" ; " " ] ;
5 | [ "<" ; " " ] ;
6 | [ ">" ; " " ] ;
7 | [ "..." ; "." ] ;
8 | [ "\"" ; "" ] ;
9 | [ "," ; "" ]
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: TextEncodeForFilePath ( text )
15 | PURPOSE: Ensures all characters in text are valid for a file path
16 | EXAMPLES:
17 |
18 | HISTORY:
19 | Created: 2011-03-03 17:47 PST - Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/TextEscapeForCSV.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~text = Substitute ( text ; "\"" ; "\"\"" )
3 | ] ;
4 | If (
5 | Position ( ~text ; "," ; 1 ; 1 )
6 | or Position ( ~text ; "¶" ; 1 ; 1 ) ;
7 | "\"" & ~text & "\"" ;
8 | ~text
9 | )
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: TextEscapeForCSV ( text )
15 | PURPOSE: Ensures text is valid csv value
16 | TESTS:
17 | List (
18 | TextEscapeForCSV ( "foo" ) = "foo" ;
19 | TextEscapeForCSV ( "foo," ) = "\"foo,\"" ;
20 | TextEscapeForCSV ( "foo\"" ) = "foo\"\""
21 | )
22 |
23 | HISTORY:
24 | Created: 2013-12-03 15:40 PT - Donovan Chandler
25 | Modified:
26 | */
--------------------------------------------------------------------------------
/TextEscapeSearchChars.calc:
--------------------------------------------------------------------------------
1 | Substitute ( searchString ;
2 | [ "\@" ; "@" ] ;
3 | [ "@" ; "\@" ] ;
4 |
5 | [ "\#" ; "#" ] ;
6 | [ "#" ; "\#" ] ;
7 |
8 | [ "\*" ; "*" ] ;
9 | [ "*" ; "\*" ] ;
10 |
11 | [ "\!" ; "!" ] ;
12 | [ "!" ; "\!" ] ;
13 |
14 | [ "\?" ; "?" ] ;
15 | [ "?" ; "\?" ] ;
16 |
17 | // Disabled because it was destroying the "today" operator (//)
18 | // [ "\/" ; "/" ] ;
19 | // [ "/" ; "\/" ] ;
20 |
21 | [ "\<" ; "<" ] ;
22 | [ "<" ; "\<" ] ;
23 |
24 | [ "\>" ; ">" ] ;
25 | [ ">" ; "\>" ] ;
26 |
27 | [ "\≤" ; "≤" ] ;
28 | [ "≤" ; "\<" ] ;
29 |
30 | [ "\≥" ; "≥" ] ;
31 | [ "≥" ; "\≥" ] ;
32 |
33 | [ "\=" ; "=" ] ;
34 | [ "=" ; "\=" ]
35 | )
36 |
37 | /* __________________________________________________
38 |
39 | NAME: TextEscapeSearchChars ( searchString )
40 | PURPOSE: Escapes reserved characters in search strings.
41 | EXAMPLES:
42 | TextEscapeSearchChars ( "<20" ) = "\<20"
43 | HISTORY:
44 | Created: 2011-03-01 15:12 PT - Donovan Chandler
45 | */
--------------------------------------------------------------------------------
/TextFilterToText.calc:
--------------------------------------------------------------------------------
1 | //Filter( string; " !#$%&'()*+,-./:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`{|}~" )
2 |
3 | Substitute( string;
4 | [ "0"; "" ];
5 | [ "1"; "" ];
6 | [ "2"; "" ];
7 | [ "3"; "" ];
8 | [ "4"; "" ];
9 | [ "5"; "" ];
10 | [ "6"; "" ];
11 | [ "7"; "" ];
12 | [ "8"; "" ];
13 | [ "9"; "" ]
14 | )
15 |
16 | /* —————————————————————————————— //
17 | NAME:
18 | TextFilterToAlpha( string )
19 |
20 | PURPOSE:
21 | Returns string with numbers removed
22 |
23 | EXAMPLES:
24 | TextFilterToText( "number10!" ) = "number!"
25 |
26 | HISTORY:
27 | Created: 2010-Sep-14 17h51 PST — Donovan A. Chandler
28 | */
--------------------------------------------------------------------------------
/TextInjected?.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | PatternCount ( text ; "SELECT" ) ;
3 | "Possible injection: SELECT" ;
4 | PatternCount ( text ; "UPDATE" ) ;
5 | "Possible injection: UPDATE" ;
6 | PatternCount ( text ; "INSERT INTO" ) ;
7 | "Possible injection: INSERT INTO" ;
8 | PatternCount ( text ; "DELETE FROM" ) ;
9 | "Possible injection: DELETE FROM" ;
10 | PatternCount ( text ; "CREATE TABLE" ) ;
11 | "Possible injection: CREATE TABLE" ;
12 | PatternCount ( text ; "ALTER TABLE" ) ;
13 | "Possible injection: ALTER TABLE" ;
14 | PatternCount ( text ; "CREATE INDEX" ) ;
15 | "Possible injection: CREATE INDEX" ;
16 | PatternCount ( text ; "DROP INDEX" ) ;
17 | "Possible injection: DROP INDEX"
18 | )
19 |
20 |
21 | /* __________________________________________________
22 |
23 | NAME: TextInjected? ( text )
24 | PURPOSE: Returns warning if possibly harmful SQL may be present into string (possible injection attack).
25 | Used to prevent SQL from being injected into evaluated strings.
26 | EXAMPLES:
27 |
28 | HISTORY:
29 | 2014-08-29 11:55 PDT - Donovan Chandler
30 | */
--------------------------------------------------------------------------------
/TextInsertAtCursor.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | text = Get ( ActiveFieldContents ) ;
3 | strNew = insertString ;
4 | curStart = Get ( ActiveSelectionStart ) ;
5 | curLen = Get ( ActiveSelectionSize ) ;
6 | strLeft = Left ( text ; curStart -1 ) ;
7 | strRight = Middle ( text ; curStart + curLen ; Length ( text ) )
8 | ] ;
9 | strLeft & strNew & strRight
10 | )
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | TextInsertAtCursor ( insertString )
15 |
16 | PURPOSE:
17 | Returns contents of active field with insertString pasted at cursor.
18 | Replaces selection.
19 |
20 | EXAMPLES:
21 |
22 |
23 | HISTORY:
24 | Created: 2011-Mar-03 17h19 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/TextIsDate.calc:
--------------------------------------------------------------------------------
1 | not IsEmpty( string ) and
2 | GetAsText ( GetAsDate( string ) ) = GetAsText ( string )
3 |
4 | /* —————————————————————————————— //
5 | NAME:
6 | TextIsDate( string )
7 |
8 | PURPOSE:
9 | Returns True if string is a date
10 |
11 | EXAMPLES:
12 |
13 |
14 | HISTORY:
15 | Created: 2010-Aug-26 11h20 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/TextMergeTags.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | tagCount = ValueCount ( mergeTagNames ) ;
3 | label = GetValue ( mergeTagNames ; 1 ) ;
4 | value = Evaluate ( GetValue ( mergeValues ; 1 ) ) ;
5 | result = Substitute ( text ; mergeTagOpen & label & mergeTagClose ; Quote ( value ) )
6 | ] ;
7 | Case (
8 | tagCount > 1 ;
9 | TextMergeTags (
10 | result ;
11 | RightValues ( mergeTagNames ; tagCount - 1 ) ;
12 | RightValues ( mergeValues ; tagCount - 1 ) ;
13 | mergeTagOpen ;
14 | mergeTagClose
15 | ) ;
16 | result
17 | )
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | TextMergeTags ( text ; mergeTagNames ; mergeValues ; mergeTagOpen ; mergeTagClose )
23 |
24 | PURPOSE:
25 | Replaces mergeLabels in text with corresponding mergeValues
26 |
27 | EXAMPLES:
28 | TextMergeTags ( "Middle ( {text} ; {start} ; 1 )"
29 | ; "text¶start"
30 | ; "\"dog\"¶\"5\""
31 | ; "{"
32 | ; "}"
33 | ) = "Middle ( \"dog\" ; 5 ; 1 )"
34 |
35 | NOTES:
36 | mergeValues - each value must be quoted (to escape multi-line values)
37 |
38 | HISTORY:
39 | Created: 2011-Dec-22 21h31 PST — Donovan A. Chandler
40 | */
--------------------------------------------------------------------------------
/TextNthNodePosition.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | sNext = Position ( text ; openChars ; startPosition ; 1 ) ;
3 | eNext = TextClosePosition ( text ; openChars ; closeChars ; sNext )
4 | ];
5 | Case (
6 | sNext = 0 ; "" ;
7 | nodeIndex = 1 ; sNext ;
8 | TextNthNodePosition ( text ; openChars ; closeChars ; eNext ; nodeIndex - 1 )
9 | )
10 | )
11 |
12 | /* __________________________________________________
13 |
14 | NAME: TextNthNodePosition( text ; openChars ; closeChars ; startPosition ; nodeIndex )
15 | PURPOSE:
16 | Returns start position of Nth "node".
17 | Each node is demarcated by openChars and closeChars.
18 | EXAMPLES:
19 | Where $_text = "[ [1,2], [3] ],[ 4 ]"
20 | TextNthNodePosition ( $_text ; "[" ; "]" ; 1 ; 2 ) = 16
21 | HISTORY:
22 | Created: 2009-12-03 12:00 PT - Donovan Chandler
23 | Modified:
24 | */
--------------------------------------------------------------------------------
/TextOmitChars.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | string = Substitute ( text ; Left ( charactersToOmit ; 1 ) ; "" ) ;
3 | charRemaining = Right ( charactersToOmit ; Length ( charactersToOmit ) - 1 )
4 | ];
5 | Case (
6 | IsEmpty ( charRemaining ) ; string ;
7 | TextOmitChars ( string ; charRemaining )
8 | )
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | TextOmitChars ( text ; charactersToOmitToOmit )
14 |
15 | PURPOSE:
16 | Removes each character from text. Functional inverse of Filter()
17 |
18 | EXAMPLES:
19 | TextOmitChars ( "23 Main Ave" ; "0123456789" ) = " Main Ave"
20 |
21 | HISTORY:
22 | Created: 2010-Dec-17 14h25 PST — Donovan A. Chandler
23 | */
--------------------------------------------------------------------------------
/TextPadColumn.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | length = Length ( col1Value ) ;
3 | tabNum = Ceiling ( (tabMax*tabSize-length) / tabSize ) ;
4 | tabNum = If ( tabNum < tabMin ; tabMin ; tabNum ) ;
5 | placeholder = Substitute ( 10^(tabNum-1) ; "0" ; 1 ) ;
6 | tabs = Substitute ( placeholder ; 1 ; " " )
7 | ];
8 | If ( not hideCol1 ; col1Value ) & tabs & col2Value
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | TextPadColumn ( col1Value ; col2Value ; tabMax ; tabMin ; tabSize ; hideCol1 )
14 |
15 | PURPOSE:
16 | Pads col2 (second column) with tab characters so that it is left-aligned regardless of col1 width.
17 | Requires monospaced font for effect to work.
18 |
19 | EXAMPLES:
20 | List (
21 | TextPadColumn ( "bold" ; "Darker text" ; 3 ; 1 ; 5 ) ;
22 | TextPadColumn ( "lightest" ; "Not so dark" ; 3 ; 1 ; 5)
23 | )
24 |
25 | HISTORY:
26 | Created: 2011-Mar-18 18h33 PST — Donovan A. Chandler
27 | */
--------------------------------------------------------------------------------
/TextPrependWithTimestamp.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | clrA = RGB ( 189 ; 76 ; 0 ) ; //Orange///
3 | clrB = RGB ( 85 ; 85 ; 85 ) //Gray//
4 | ];
5 | Case (
6 | not IsEmpty ( newText ) ;
7 | GetAsDate ( timestmp ) & " " &
8 | TextColor ( GetAsTime ( timestmp ) & " by " ; clrB ) &
9 | TextColor ( name ; clrA ) &
10 | TextColor (
11 | ":¶" &
12 | "-------------------------------------------------¶" ; clrB
13 | ) &
14 | newText &
15 | Case (
16 | not IsEmpty ( oldText ) ;
17 | "¶¶" & oldText
18 | )
19 | )
20 | )
21 |
22 |
23 |
24 | /* —————————————————————————————— //
25 | NAME:
26 | TextPrependWithTimestamp ( oldText ; newText ; name ; timestmp )
27 |
28 | PURPOSE:
29 | Prepends block of text with header containing provided name and timestamp
30 |
31 | EXAMPLES:
32 |
33 |
34 | HISTORY:
35 | Created: 2010-Dec-21 12h25 PST — Donovan A. Chandler
36 | */
--------------------------------------------------------------------------------
/TextRepeatWithIncrement.calc:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | NAME:
3 | text.repeatWithIncrement( text; matchString; startValue; endValue )
4 |
5 | PURPOSE:
6 | Repeats text, incrementing matchString from startNumber to endNumber.
7 |
8 | HISTORY:
9 | Created 2010-Mar-20 16h02 donovan_c@beezwax.net
10 |
11 | INPUT:
12 |
13 |
14 | OUTPUT:
15 |
16 | ---------------------------------------------------------------------------------------*/
17 |
18 | Let([
19 | _text = text;
20 | _matchString = matchString;
21 | _numStart = startValue;
22 | _numEnd = endValue;
23 |
24 | _sMatch = Position( _text; _matchString; 1; 1 );
25 | _textNew = Replace( _text; _sMatch; Length( _matchString ); _numStart )
26 | ];
27 | Case(
28 | //-- Invalid matchString
29 | _sMatch = 0;
30 | _text;
31 |
32 | //-- More values to add
33 | _numStart < _numEnd;
34 | _textNew & text.repeatWithIncrement( _text; _matchString; _numStart + 1; _numEnd );
35 |
36 | //-- Default
37 | _textNew
38 | )
39 | )
--------------------------------------------------------------------------------
/TextSplit.calc:
--------------------------------------------------------------------------------
1 | ListTrimValues (
2 | Substitute ( text ; splitChar ; ¶ )
3 | )
4 |
5 | /* —————————————————————————————— //
6 | NAME:
7 | TextSplit ( text ; splitChar )
8 |
9 | PURPOSE:
10 | Breaks text string on splitChar into return-delimited list.
11 | Also strips whitespace from ends of each line.
12 |
13 | EXAMPLES:
14 | TextSplit ( "dog, cat ,mouse" ; "," ) = "dog¶cat¶mouse"
15 |
16 | HISTORY:
17 | Created: 2011-Mar-08 09h33 PST — Donovan A. Chandler
18 | */
--------------------------------------------------------------------------------
/TextStripLeft.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | Left ( text ; 1 ) = charToStrip ;
3 | TextStripLeft ( Right ( text ; Length ( text ) - 1 ) ; charToStrip ) ;
4 | text
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TextStripLeft ( text ; charToStrip )
10 | PURPOSE: Strips all occurrences of character from beginning of text
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2011-07-09 21:26 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/TextStripRight.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | Right ( text ; 1 ) = charToStrip ;
3 | TextStripRight ( Left ( text ; Length ( text ) - 1 ) ; charToStrip ) ;
4 | text
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TextStripRight ( text ; charToStrip )
10 | PURPOSE: Strips all occurrences of character from end of text
11 | EXAMPLES:
12 | TextStripRight ( "test:" ; ":" ) //= "test"
13 | TextStripRight ( "test: " ; ":" ) //= "test: "
14 | TextStripRight ( "test: " ; ": " ) //= "test: "
15 | HISTORY:
16 | Created: 2011-07-09 21:26 PT - Donovan Chandler
17 | Modified:
18 | */
--------------------------------------------------------------------------------
/TimeDurationAsText.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | then = GetAsTimestamp ( startTimestamp ) ;
3 | now = GetAsTimestamp ( endTimestamp ) ;
4 | dur = now - then ;
5 | hours = Hour ( dur ) ;
6 | days = Int ( Div ( hours ; 24 ) ) ;
7 | hours = Mod ( hours ; 24 ) ;
8 | mins = Minute ( dur )
9 | ] ;
10 | Case (
11 | IsEmpty ( startTimestamp ) or IsEmpty ( endTimestamp ) ; "" ;
12 | days > 0 ; days & " day" & If ( days > 1 ; "s" ) ;
13 | hours > 0 ; hours & " hour" & If ( hours > 1 ; "s" ) ;
14 | mins > 0 ; mins & " min" & If ( mins > 1 ; "s" )
15 | )
16 | )
17 |
18 | /* __________________________________________________
19 |
20 | NAME: TimeDurationAsText ( startTimestamp ; endTimestamp )
21 | PURPOSE: Returns text description of duration, using largets denominator only.
22 | EXAMPLES:
23 | TimeDurationAsText ( "1/1/2012" ; "1/14/2012" ) = "13 days"
24 | TimeDurationAsText ( "1/1/2012 12:00 PM" ; "1/1/2012 1:00 PM" ) = "1 hour"
25 | TimeDurationAsText ( "1/1/2012 12:00 PM" ; "1/1/2012 12:38 PM" ) = "38 mins"
26 | HISTORY:
27 | Created: 2012-10-15 15:37 PT - Donovan Chandler
28 | Modified:
29 | */
--------------------------------------------------------------------------------
/TimeStampAsZulu.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | timeZ =
3 | Time (
4 | Hour ( tme ) + ( hourOffsetFromZulu * -1 ) ;
5 | Minute ( tme ) ;
6 | Seconds ( tme )
7 | ) ;
8 | m = Timestamp ( dte ; timeZ );
9 | d = Date ( Month ( m ) ; Day ( m ) ; Year ( m ) );
10 | t = Time ( Hour ( m ) ; Minute ( m ) ; Seconds ( m ) )
11 | ] ;
12 | Year ( d ) &
13 | "-" &
14 | Right ( "00" & Month ( d ) ; 2 ) &
15 | "-" &
16 | Right ( "00" & Day ( d ) ; 2 ) &
17 | "T" &
18 | Right ( "00" & Hour ( t ) ; 2 ) &
19 | ":" &
20 | Right ( "00" & Minute ( t ) ; 2 ) &
21 | ":" &
22 | Right ( "00" & Seconds ( t ) ; 2 ) & ".000Z"
23 | )
24 |
25 | /* —————————————————————————————— //
26 | NAME:
27 | TimestampAsZulu ( dte ; tme ; hourOffsetFromZulu )
28 |
29 | PURPOSE:
30 | Takes timestamp and returns equivalent time in Zulu (GMT) forma
31 |
32 | EXAMPLES:
33 | TimestampAsZulu ( "12/1/10" ; "1:05 PM" ; -8 )
34 | = "2010-12-01T21:00:05.000Z"
35 |
36 | HISTORY:
37 | Created: 2010-Dec-01 12h09 PST — Donovan A. Chandler based on function by Vincenzo Menanno
38 | */
39 |
--------------------------------------------------------------------------------
/TimeStampMicroUTC.calc:
--------------------------------------------------------------------------------
1 | GetAsTimestamp ( Get ( UTCmSecs ) / 1000 )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: TimestampMicroUTC ( )
6 | PURPOSE: Returns UTC timestamp including microseconds.
7 | EXAMPLES:
8 | TimestampMicroUTC() = "11/9/2012 1:16:13.056 PM"
9 | HISTORY:
10 | Created: 2012-11-09 13:13 PT - Donovan Chandler using David Thorpe's calc.
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/TimeZone.calc:
--------------------------------------------------------------------------------
1 | ( Get ( CurrentTimeStamp ) - Int ( Get ( UTCmSecs ) / 1000 ) ) / 3600
2 |
3 | /* __________________________________________________
4 |
5 | NAME: TimeZone ( )
6 | PURPOSE: Returns hour offset of timezone
7 | EXAMPLES:
8 | TimeZone // returns "-8" when in PST
9 | HISTORY:
10 | Created: 2012-11-09 13:07 PT - Donovan Chandler using David Thorpe's calc.
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/TimestampFromText.calc:
--------------------------------------------------------------------------------
1 | Let ([
2 | day = LeftWords ( text ; 1 ) ;
3 | month = DateMonthNumber ( MiddleWords ( text ; 2 ; 1 ) ) ;
4 | year = MiddleWords ( text ; 3 ; 1 ) ;
5 | time = Middle ( text ; Position ( text ; " " ; 1 ; 1 ) ; 999 )
6 | ];
7 | If (
8 | not IsEmpty ( text ) ;
9 | Timestamp ( Date ( month ; day ; year ) ; GetAsTime ( time ) )
10 | )
11 | )
12 |
13 | /* —————————————————————————————— //
14 | NAME:
15 | TimestampFromText ( text )
16 |
17 | PURPOSE:
18 | Converts text from text timestamp into a date
19 |
20 | EXAMPLES:
21 | TimestampFromText ( "23-JUL-2010 16:02" ) = "7/23/2010 4:02 PM"
22 |
23 | HISTORY:
24 | Created: 2011-Jun-14 11h51 PST — Donovan A. Chandler
25 | */
--------------------------------------------------------------------------------
/TimestampFromUnix.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | unixDiff = 62135596800 // GetAsNumber ( GetaSTimestamp ( "1/1/1970" ) )
3 | ; timezoneDiff = 60 * 60 * currentTimezone
4 | ] ;
5 | GetAsTimestamp ( unixTimestampNumber + unixDiff + timezoneDiff )
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | TimestampFromUnix ( unixTimestampNumber ; currentTimezone )
11 |
12 | PURPOSE:
13 | Converts unix timestamp ("epoch time") to FileMaker timestamp.
14 | Epoch time is stored as the number of seconds since midnight 1/1/1970 UTC/GMT.
15 |
16 | EXAMPLES:
17 | TimestampFromUnix ( 1329931434 ; -8 ) = "2/22/2012 9:23:53 AM"
18 |
19 | HISTORY:
20 | Created: 2012-Feb-22 14h29 PST — Donovan A. Chandler
21 | */
--------------------------------------------------------------------------------
/TimestampMicro.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | timezoneSec = Get ( CurrentTimeStamp ) - Int ( Get ( UTCmSecs ) / 1000 )
3 | ] ;
4 | GetAsTimestamp ( ( Get ( UTCmSecs ) / 1000 ) + timezoneSec )
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TimestampMicro()
10 | PURPOSE: Returns local timestamp including microseconds.
11 | Use TimeStampMicroUTC() for faster results.
12 | EXAMPLES:
13 | TimestampMicro() = "11/9/2012 1:16:13.056 PM"
14 | HISTORY:
15 | Created: 2010-08-06 18:16 PT - Donovan Chandler
16 | Modified: 2012-11-09 13:06 PT - Donovan Chandler : Implemented David Thorpe's native version.
17 | */
--------------------------------------------------------------------------------
/TraceAdd.calc:
--------------------------------------------------------------------------------
1 | If (
2 | not TraceIsOn ; "Trace log disabled" ;
3 |
4 | Let ( [
5 | delim = " " ;
6 | row = Get ( UTCmSecs ) / 1000 & delim & objectName & delim & objectType & delim & action & delim & note ;
7 | $$_trace_log = List ( $$_trace_log ; row )
8 | ] ;
9 | row
10 | )
11 | )
12 |
13 | /* __________________________________________________
14 |
15 | NAME: LogTimeAdd ( objectName ; objectType ; action ; note )
16 | PURPOSE: Appends entry to trace log in global variable.
17 | EXAMPLE:
18 | LogTimeAdd ( "record . delete" ; "Script" ; "Start" ; "note…" ) & TraceLog
19 | = "163491021512.292 record . delete Script Start note…"
20 | PARAMETERS:
21 | The parameters are all optional and for your discretion.
22 | I use them for parsing the log in a fashion inspired by FMBench.
23 |
24 | objectName Name of script, etc.
25 | objectType {script, calc}
26 | action {start, end, debug, error}
27 | Use "start" and "end" to determine the length of a script.
28 | NOTES:
29 | Optimized more for speed and ease of use.
30 | Use FMBench if you're looking for something robust.
31 | HISTORY:
32 | Created: 2012-04-11 10:34 PT - Donovan Chandler
33 | Modified:
34 | */
--------------------------------------------------------------------------------
/TraceAddSQL.calc:
--------------------------------------------------------------------------------
1 | If (
2 | not TraceIsOn ; "Trace log disabled" ;
3 |
4 | Let ( [
5 | fdTimestamp = GetFieldName ( performance_log::timestamp_value ) ;
6 | fdScript = GetFieldName ( performance_log::script_name ) ;
7 | fdMessage = GetFieldName ( performance_log::note ) ;
8 | ts = sqlPrepTimestampForInsert ( GetAsTimestamp ( TimestampMicro ) ) ;
9 | query = "INSERT INTO " & SQLTable ( fdScript ) & " ( " &
10 | SQLField ( fdTimestamp ) & ", " & SQLField ( fdScript ) & ", " & SQLField ( fdMessage ) &
11 | " ) VALUES ( " &
12 | ts & ", " & SQLString ( objectName ) & ", " & SQLString ( note ) &
13 | " )"
14 | ] ;
15 | sql ( query )
16 | )
17 | )
18 |
19 | /* __________________________________________________
20 |
21 | NAME: TraceAddSQL ( objectName ; objectType ; action ; note )
22 | PURPOSE: Creates trace log entry directly into log table using SQL plug-in.
23 | NOTES:
24 | Requires SQL plug-in supporting INSERT statements.
25 | Optimized more for speed and ease of use.
26 | Use FMBench if you're looking for something robust.
27 | HISTORY:
28 | Created: 2012-09-17 11:59 PT - Donovan Chandler
29 | Modified:
30 | */
--------------------------------------------------------------------------------
/TraceClear.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_trace_log = ""
3 | ] ;
4 | $$_trace_log
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TraceClear ( )
10 | PURPOSE: Clears values from trace log. Large logs can impact performance.
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2012-09-07 17:25 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/TraceIsOn.calc:
--------------------------------------------------------------------------------
1 | $$_trace_enabled
2 |
3 | /* __________________________________________________
4 |
5 | NAME: TraceIsOn ( )
6 | PURPOSE: Returns True if trace log is enabled.
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2012-09-07 16:20 PST - Donovan Chandler
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/TraceLog.calc:
--------------------------------------------------------------------------------
1 | $$_trace_log
2 |
3 | /* __________________________________________________
4 |
5 | NAME: TraceLog ( )
6 | PURPOSE: Displays trace log being managed by Trace function suite.
7 | EXAMPLES:
8 |
9 | HISTORY:
10 | Created: 2012-09-07 17:25 PT - Donovan Chandler
11 | Modified:
12 | */
--------------------------------------------------------------------------------
/TraceOff.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_trace_enabled = False // Keeps variable so we can toggle it in the web viewer
3 | ] ;
4 | $$_trace_enabled
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TraceOff ( )
10 | PURPOSE: Disables trace log. Ensures scripts don't get bogged down unnecessarily.
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2012-09-07 16:21 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/TraceOn.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | $$_trace_enabled = True
3 | ] ;
4 | $$_trace_enabled
5 | )
6 |
7 | /* __________________________________________________
8 |
9 | NAME: TraceOn ( )
10 | PURPOSE: Enables trace log.
11 | EXAMPLES:
12 |
13 | HISTORY:
14 | Created: 2012-09-07 16:21 PT - Donovan Chandler
15 | Modified:
16 | */
--------------------------------------------------------------------------------
/TrimCRLF.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | delimiter = "::‡::" ;
3 | result1 =
4 | Substitute (
5 | Trim (
6 | Substitute ( text ;
7 | [ " " ; delimiter ] ;
8 | [ ¶ ; " " ]
9 | )
10 | ) ;
11 | [ " " ; ¶ ] ;
12 | [ delimiter ; " " ]
13 | ) ;
14 | result2 =
15 | Substitute (
16 | Trim (
17 | Substitute ( result1 ;
18 | [ " " ; delimiter ] ;
19 | [ Char ( 10 ) ; " " ]
20 | )
21 | ) ;
22 | [ " " ; Char ( 10 ) ] ;
23 | [ delimiter ; " " ]
24 | )
25 | ] ;
26 | result2
27 | )
28 |
29 | /* —————————————————————————————— //
30 | NAME:
31 | TrimCRLF ( text )
32 |
33 | PURPOSE:
34 | Trims leading and trailing carriage returns and line feeds from text
35 |
36 | HISTORY:
37 | Created: 2009-Jan-13 — Charlie (http://www.fmfunctions.com/mid/132)
38 | Adapted: 2010-Aug-09 10h17 PST — Donovan A. Chandler
39 | Adapted: 2011-Sep-28 14h38 PST — Donovan Chandler ; added LF removal
40 | */
--------------------------------------------------------------------------------
/TrimCRLeft.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | char = Left ( text ; 1 )
3 | ] ;
4 | Case (
5 | char = "¶" ;
6 | TrimCRLeft ( Right ( text ; Length ( text ) - 1 ) ) ;
7 | text
8 | )
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | TrimCRLeft ( text )
14 |
15 | PURPOSE:
16 | Trims leading carriage returns from text.
17 |
18 | EXAMPLES:
19 | TrimCRLeft ( "¶¶foo¶¶" ) = "foo¶¶"
20 |
21 | HISTORY:
22 | Created: 2011-Oct-31 14h41 PST — Donovan A. Chandler
23 | */
--------------------------------------------------------------------------------
/TrimCRRight.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | char = Right ( text ; 1 )
3 | ] ;
4 | Case (
5 | char = "¶" ;
6 | TrimCRRight ( Left ( text ; Length ( text ) - 1 ) ) ;
7 | text
8 | )
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: TrimCRRight ( text )
14 | PURPOSE: Trims trailing carriage returns from text.
15 | EXAMPLES:
16 | TrimCRRight ( "¶¶foo¶¶" ) = "¶¶foo"
17 | HISTORY:
18 | Created: 2011-10-31 14:41 PST - Donovan A. Chandler
19 | */
20 |
--------------------------------------------------------------------------------
/TrimChar.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | delimiter = "::‡::" ;
3 | char = GetValue ( charsToTrimList ; 1 ) ;
4 | char =
5 | Case (
6 | not IsEmpty ( char ) ; char ;
7 | not IsEmpty ( charsToTrimList ) ; charsToTrimList ; // accounts for LF
8 | ""
9 | ) ;
10 | result =
11 | Substitute (
12 | Trim (
13 | Substitute ( text ;
14 | [ " " ; delimiter ] ;
15 | [ char ; " " ]
16 | )
17 | ) ;
18 | [ " " ; char ] ;
19 | [ delimiter ; " " ]
20 | )
21 | ] ;
22 | Case (
23 | ValueCount ( charsToTrimList ) > 1 ;
24 | TrimChars ( result ; LeftWords ( MiddleValues ( charsToTrimList ; 2 ; 999 ) ; 999 ) ) ;
25 | result
26 | )
27 | )
28 |
29 | /* —————————————————————————————— //
30 | NAME:
31 | TrimChars ( text ; charsToTrimList )
32 |
33 | PURPOSE:
34 | Trims leading and trailing occurrences of character from text
35 |
36 | NOTES:
37 | Does NOT work with consecutive line terminators like CR and LF
38 |
39 | HISTORY:
40 | Created: 2011-Jul-09 21h26 PST — Donovan Chandler
41 | Modified: 2011-Sep-28 14h22 PST — Donovan Chandler ; now accepts list of chars to trim
42 | */
--------------------------------------------------------------------------------
/TrimWhitespaceLeft.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~char = Left ( text ; 1 ) ;
3 | ~charToTrim =
4 | "¶"
5 | & " "
6 | & Char ( 9 ) /* TAB */
7 | & Char ( 10 ) /* LF */
8 | ] ;
9 | Case (
10 | not IsEmpty ( Filter ( ~char ; ~charToTrim ) ) ;
11 | TrimWhitespaceLeft ( Right ( text ; Length ( text ) - 1 ) ) ;
12 | text
13 | )
14 | )
15 |
16 | /* __________________________________________________
17 |
18 | NAME: TrimWhitespaceLeft ( text )
19 | PURPOSE: Removes leading whitespace from text.
20 | EXAMPLES:
21 | TrimWhitespaceLeft ( "¶ ¶text¶" ) = "text¶"
22 | HISTORY:
23 | 2013-09-27 12:13 PT - Donovan Chandler
24 | */
--------------------------------------------------------------------------------
/URLHash.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | pos = Position ( url ; "#" ; 1 ; 1 )
3 | ] ;
4 | If (
5 | pos > 0 ; Middle ( url ; pos ; Length ( url ) )
6 | )
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: URLHash ( url )
12 | PURPOSE: Returns hash portion of URL. Used for extracting info from web viewer.
13 | Web viewer must be referencing an external file for you to alter the url.
14 | Use GetLayoutObjectAttribute ( "wv_object" ; "sournce" ) to get the url.
15 | EXAMPLES:
16 | URLHash ( "file://tmp/page.html#paramForScript" ) = "paramForScript"
17 | HISTORY:
18 | Created: 2012-04-27 10:12 PST - Donovan Chandler
19 | Modified:
20 | */
--------------------------------------------------------------------------------
/URLParam.calc:
--------------------------------------------------------------------------------
1 | TextBetween ( url & "&" ; name & "=" ; "&" ; 1 )
2 |
3 | /* __________________________________________________
4 |
5 | NAME: URLParam ( url ; name )
6 | PURPOSE: Retrieves parameter value from url.
7 | Doesn't parse or decode full url because OnTimer script usually handles that.
8 | EXAMPLES:
9 | URLParam ( "http://domain.com#animal=dog&food=donuts%20" ; "food" ) = "donuts%20"
10 | HISTORY:
11 | Created: 2012-06-21 16:00 PST - Donovan Chandler
12 | Modified:
13 | */
--------------------------------------------------------------------------------
/URLSelf.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~isHosted = PatternCount ( Get ( HostApplicationVersion ) ; "Server" )
3 | ] ;
4 | "fmp://" &
5 | If ( ~isHosted ; PathStripPrefix ( Get ( FilePath ) ) ; "$/" & Get ( FileName ) ) &
6 | If ( Length ( script ) ; "?script=" & script & If ( Length ( parameter ) ; "¶m=" & parameter ) )
7 | )
8 |
9 | /* __________________________________________________
10 |
11 | NAME: URLSelf ( script ; parameter )
12 | PURPOSE: Returns fmp:// url for calling script in current FileMaker file.
13 | EXAMPLES:
14 |
15 | HISTORY:
16 | Created: 2012-04-27 11:56 PST - Donovan Chandler
17 | Modified: 2014-04-03 14:05 PDT - Donovan Chandler : Incorporate Will M. Baker's mods for FMP 13.0v3 support for local references.
18 | */
--------------------------------------------------------------------------------
/UserIsFullAccess.calc:
--------------------------------------------------------------------------------
1 | Get ( AccountPrivilegeSetName ) = "[Full Access]"
2 |
3 | /* __________________________________________________
4 |
5 | NAME: UserIsFullAccess ( )
6 | PURPOSE: Returns True if user has full access privileges
7 | HISTORY:
8 | Created: 2012-09-12 PST -27 16h16 PST — Donovan A. Chandler
9 | */
--------------------------------------------------------------------------------
/VarAssign.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | names = VarAssignLoop ( encodedString ; listOfParams ) ;
3 | error = If ( IsEmpty ( names ) ; 0 ; 10 )
4 | ] ;
5 | If (
6 | error ≠ 0 ;
7 | Let ( [
8 | count = ValueCount ( names ) ;
9 | str = Substitute ( names ; ¶ ; ", " ) ;
10 | msg = "Missing/invalid parameter" & If ( count > 1 ; "s" )
11 | & ": " & str ;
12 | v = VarSet ( "_invalid_params" ; names ; "t" ; False ) ;
13 | v = VarSet ( "_error_message" ; msg ; "t" ; False )
14 | ] ;
15 | ""
16 | )
17 | )
18 | & error
19 | )
20 |
21 | /* __________________________________________________
22 |
23 | NAME: VarAssign ( encodedString ; listOfParams )
24 | PURPOSE: Instantiates variables from dictionary, with optional type casting and validation.
25 | EXAMPLES: See VarAssignMan() for documentation.
26 | HISTORY:
27 | Created: 2012-03-16 09:15 PST - Donovan Chandler
28 | Modified:
29 | */
--------------------------------------------------------------------------------
/VarAssign.fmfn:
--------------------------------------------------------------------------------
1 | Let ( [
2 | _S = If ( GetAsBoolean ( isGlobal ) ; "$$" ; "$" ) ;
3 | exError = "IsEmpty ( " & _S & name & ")"
4 | ] ;
5 | Evaluate (
6 | "Let([" & _S & name & "=" & Quote ( value ) & "];" & exError & ")"
7 | )
8 | )
9 |
10 | /*---------------------------------------------------------------------------------------
11 | NAME:
12 | VarSet ( name ; value ; isGlobal )
13 |
14 | PURPOSE:
15 | Instantiates local or global variable
16 |
17 | HISTORY:
18 | Created 2008-Sep-24 — Donovan Chandler
19 |
20 | OUTPUT:
21 | Assigns local or global variable, returning "1" if variable is empty (else 0)
22 |
23 | EXAMPLE:
24 | VarSet ( "_tab_list" ; "tab_1" ; 1 ) = 0, sets $$_tab_list to "tab_1"
25 | VarSet ( "_tab_list" ; "" ; 1 ) = 1, = 1, sets $$_tab_list to null
26 | ---------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------
/VarAssignWithLog.fmfn:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | •••• INCOMPLETE ••••
3 |
4 | NAME:
5 | var.assignWithLog( name; value; global; nameOfVariableLog )
6 | Version 1.2
7 |
8 | PURPOSE:
9 | Instantiates local or global variable according to parameters
10 |
11 | HISTORY:
12 | Created 2010.06.04 by DChandler
13 |
14 | INPUT:
15 | name: Name of variable (text string)
16 | value: Value of variable (text string)
17 | global: (Boolean) - True creates variable as global
18 |
19 | OUTPUT:
20 | Assigns local or global variable, returning "1" if variable is empty (else 0)
21 | ---------------------------------------------------------------------------------------*/
22 |
23 | Let([
24 | _log = nameOfVariableLog
25 | ; _S = Case( global; "$$"; "$" )
26 | ; _var = _S & name
27 | ; exError = "IsEmpty( " & _var & ") or " & _var & "=\"?\""
28 | ];
29 | Evaluate( "Let([" &
30 | _var & "=" & Quote(value) & ";" &
31 | "$$" & _log & "= $$" & _log & " & " & Quote( _var ) & " & " & "\¶" &
32 | "]; " & exError & " )"
33 | )
34 | )
--------------------------------------------------------------------------------
/VarInvalid.calc:
--------------------------------------------------------------------------------
1 | VarInvalidLoop (
2 | listOfVariables ;
3 | 1 ;
4 | PatternCount ( listOfVariables ; ¶ ) + 1 ;
5 | ""
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 | VarInvalid( listOfVariables )
11 |
12 | PURPOSE:
13 | Returns list of names of variables containing invalid data
14 |
15 | EXAMPLES:
16 | (Where $_table = "CONTACT" and $_field = "")
17 |
18 | VarInvalid ( "$_table¶$_field" ) = "$_field"
19 | VarInvalid ( $_table & ¶ & $_field ) = "$_field"
20 | VarInvalid ( $_table & $_field ) = ""
21 | VarInvalid ( List ( $_table ; $_field ) ) = "" // CAUTION!!!
22 |
23 | HISTORY:
24 | Created: 2010-Aug-20 16h07 PST — Donovan A. Chandler
25 |
26 | NOTES:
27 | Be careful using the List() function with this; it will remove lines that contain no value. So this will not catch an error:
28 | VarValidate( List ( $_table ; $_field )) = 0
29 | */
--------------------------------------------------------------------------------
/VarInvalidLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | var = GetValue ( listOfVariables ; rep ) ;
3 | value =
4 | Case (
5 | Left ( var ; 1 ) = "$" ; Evaluate ( var ) ;
6 | var
7 | ) ;
8 | invalid = ( value = "?" or IsEmpty ( value ) ) ;
9 | newResults = If ( invalid ; List ( previousResults ; var ) )
10 | ] ;
11 |
12 | Case (
13 | rep < repMax ;
14 | VarInvalidLoop ( listOfVariables ; rep + 1 ; repMax ; newResults ) ;
15 | newResults
16 | )
17 | )
18 |
19 | /* —————————————————————————————— //
20 | NAME:
21 | VarInvalidLoop ( listOfVariables ; rep ; repMax ; previousResults )
22 |
23 | PURPOSE:
24 | Performs recursion for VarInvalid ()
25 |
26 | EXAMPLES:
27 |
28 |
29 | HISTORY:
30 | Created: 2010-Aug-20 16h07 PST — Donovan A. Chandler
31 | */
--------------------------------------------------------------------------------
/VarValidate.calc:
--------------------------------------------------------------------------------
1 | VarValidateLoop (
2 | listOfVariables ;
3 | 1 ;
4 | PatternCount ( listOfVariables ; ¶ ) + 1
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | VarValidate( listOfVariables )
10 |
11 | PURPOSE:
12 | Returns count of variables with invalid data
13 |
14 | EXAMPLES:
15 | (where all variables contain values other than "?")
16 |
17 | VarValidate( "$_table¶$_field" ) = 0
18 | VarValidate( $_table & ¶ & $_field ) = 0
19 | VarValidate( "¶¶" ) = 1
20 | VarValidate( List ( $_empty_var ; $_good_var )) = 0 // CAUTION!!!
21 |
22 | HISTORY:
23 | Created: 2010-Aug-20 16h07 PST — Donovan A. Chandler
24 |
25 | NOTES:
26 | Be careful using the List() function with this; it will remove lines that contain no value. So this will not catch an error:
27 | VarValidate( List ( $_empty_var ; $_good_var )) = 0
28 | */
--------------------------------------------------------------------------------
/VarValidate2.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | //-- Increment counter
3 | $$_fn_varvalidate_rep = $$_fn_varvalidate_rep + 1;
4 | _rep = $$_fn_varvalidate_rep;
5 |
6 | _var = GetValue( listOfVariables; _rep );
7 | _value =
8 | Case(
9 | Left( _var; 1 ) = "$"; Evaluate( _var );
10 | _var
11 | );
12 | _var_count = PatternCount( listOfVariables; ¶ ) + 1
13 | ];
14 | //-- Add 1 if current value is invalid
15 | Case(
16 | _value = "?" or IsEmpty( _value );
17 | 1;
18 | 0
19 | ) +
20 | //-- Iterate thru other values
21 | Case(
22 | _rep < _var_count;
23 | var.validate( listOfVariables );
24 | Let($$_fn_varvalidate_rep = ""; 0 )
25 | )
26 | )
27 |
28 | /* —————————————————————————————— //
29 | NAME:
30 | var.validate( listOfVariables )
31 |
32 | PURPOSE:
33 | Returns count of variables with invalid data
34 |
35 | EXAMPLES:
36 | (where all variables contain values other than "?")
37 |
38 | var.validate( "$_table¶$_field" ) = 0
39 | var.validate( $_table & ¶ & $_field ) = 0
40 |
41 | HISTORY:
42 | Created: 2010-Aug-20 16h07 PST — Donovan A. Chandler
43 | */
--------------------------------------------------------------------------------
/VarValidateLoop.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | var = GetValue ( listOfVariables ; rep ) ;
3 | value =
4 | Case (
5 | Left ( var ; 1 ) = "$" ; Evaluate ( var ) ;
6 | var
7 | ) ;
8 | invalid = ( value = "?" or IsEmpty ( value ) )
9 | ] ;
10 |
11 | //-- Add 1 if current value is invalid
12 | Case(
13 | value = "?" or IsEmpty( value );
14 | 1;
15 | 0
16 | ) +
17 |
18 | //-- Iterate thru other values
19 | Case (
20 | rep < repMax ;
21 | VarValidateLoop ( listOfVariables ; rep + 1 ; repMax )
22 | )
23 | )
24 |
25 | /* —————————————————————————————— //
26 | NAME:
27 | VarValidateLoop ( listOfVariables ; rep ; repMax )
28 |
29 | PURPOSE:
30 | Performs recursion for VarValidate ()
31 |
32 | EXAMPLES:
33 |
34 |
35 | HISTORY:
36 | Created: 2010-Aug-20 16h07 PST — Donovan A. Chandler
37 | */
--------------------------------------------------------------------------------
/WebNavHeader.calc:
--------------------------------------------------------------------------------
1 | If (
2 | not IsHosted ;
3 | "path to exported file" ;
4 |
5 | "Data:text/html," &
6 | WebNavHeaderSub (
7 | CodeMerge ( "‡‡CODE[1]‡‡" ) ;
8 | FOCUS::HEADER_LABELS ;
9 | ". nav . header" ;
10 | FOCUS::HEADER_INSTRUCTIONS
11 | )
12 | )
13 |
14 | /* __________________________________________________
15 |
16 | NAME: WebNavHeader
17 | PURPOSE: Generates HTML for navigation header in web viewer.
18 | NOTES:
19 | HISTORY:
20 | Created: 2012-04-14 14:15 PST - Donovan Chandler
21 | Modified:
22 | */
--------------------------------------------------------------------------------
/WebViewerFieldDisplay.calc:
--------------------------------------------------------------------------------
1 | "data:text/html,
¶
"
& GetAsCSS ( text )
& ""
/* __________________________________________________
NAME: WebTextDisplay ( text ; fontSize ; customCSSForAllElements )
PURPOSE: Displays text in web viewer.
EXAMPLES:
WebTextDisplay (
TextColor ( TABLE::FIELD ; RGB ( 255 ; 0 ; 0 ) ) ;
10 ;
"font-family:Verdana;¶"
) => Displays field contents in red, 10pt Verdana
HISTORY:
Created: 2011-09-14 13:58 PST - Donovan A. Chandler
*/
--------------------------------------------------------------------------------
/Weekdays.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | startDay = DayOfWeek ( startDate ) ; // startDate's day of the week
3 | rawRange = endDate - startDate + 1 ; // how many days there are between and inclusive of the two dates
4 | rawWeekendDays = Floor ( rawRange / 7 ) * 2 ; // weekend days included in full weeks
5 | modRange = Mod ( rawRange ; 7 ) ; // days left over, not part of full weeks
6 | modWeekendDays = Case (
7 | startDay = 1 and modRange > 0 ; 1 ;
8 | modRange > ( 8 - startDay ) ; 2 ;
9 | modRange = ( 8 - startDay ) ; 1 ;
10 | 0
11 | ) ; // weekend days included in the leftover days
12 | weekendDays = rawWeekendDays + modWeekendDays // total weekend days
13 | ] ;
14 |
15 | rawRange - weekendDays
16 |
17 | )
18 |
19 | /* —————————————————————————————— //
20 | NAME:
21 | Weekdays ( startDate ; endDate )
22 |
23 | PURPOSE:
24 | Return the number of weekdays in and inclusive of the range, excluding Saturdays and Sundays.
25 |
26 | EXAMPLES:
27 | Weekdays ( 10/11/2010 ; 10/20/2010 ) = 8
28 | Weekdays ( 10/16/2010 ; 10/25/2010 ) = 6
29 |
30 | HISTORY:
31 | Created: 2010-Oct-12 13h51 PST — Will M. Baker
32 | */
--------------------------------------------------------------------------------
/WindowGetMeasurements.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | clear = GetAsBoolean ( clearMeasurements ) ;
3 | $$_window_orig_height = If ( clear ; "" ; Get ( WindowHeight ) ) ;
4 | $$_window_orig_width = If ( clear ; "" ; Get ( WIndowWidth ) ) ;
5 | $$_window_orig_top = If ( clear ; "" ; Get ( WIndowTop ) ) ;
6 | $$_window_orig_left = If ( clear ; "" ; Get ( WindowLeft ) )
7 | ] ;
8 | ""
9 | )
10 |
11 | /* —————————————————————————————— //
12 | NAME:
13 | WindowGetMeasurements ( clearMeasurements )
14 |
15 | PURPOSE
16 | Measures location and dimensions of current window for use by WindowSetMeasurements()
17 |
18 | HISTORY:
19 | Created 2009.08.13 by Donovan Chandler
20 |
21 | INPUT:
22 | clearMeasurements: "False" or Null will set measurements. "True" will clear all variables instantiated by this function.
23 |
24 | OUTPUT:
25 | Global Variables
26 | */
--------------------------------------------------------------------------------
/calc.hideInvalid.calc:
--------------------------------------------------------------------------------
1 | If ( IsValid ( calculation ) ; calculation )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | calc.hideInvalid ( calculation )
6 |
7 | PURPOSE:
8 | Returns null if calculation result is invalid. Useful for hiding empty chart headers.
9 |
10 | EXAMPLES:
11 |
12 |
13 | HISTORY:
14 | Created: 2010-Jun-11 20h31 PST — Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/calc_PythonSendMail.calc:
--------------------------------------------------------------------------------
1 | /* __________________________________________________
2 |
3 | NAME: PythonSendMailScript ( )
4 | PURPOSE: Stores python script for use in bBox plug-in.
5 | See http://bbox.beezwax.net/ for plug-in details.
6 | HISTORY:
7 | Created: 2013-10-25 12:36 PT - Donovan Chandler
8 | Modified: 2013-11-19 17:06 PT - Donovan Chandler : optinal text body and debug level.
9 | */
10 |
11 |
12 |
--------------------------------------------------------------------------------
/calc_StripDisk.calc:
--------------------------------------------------------------------------------
1 | Let ( [
2 | ~path = "" ;
3 | ~drive = Get ( SystemDrive ) ;
4 | ~driveStart = Position ( ~path ; ~drive ; 1 ; 1 )
5 | ] ;
6 | If (
7 | ~driveStart = 0 ; ~path ;
8 | "/" & Middle ( ~path ; ~driveStart + Length ( ~drive ) ; Length ( ~path ) )
9 | )
10 | )
--------------------------------------------------------------------------------
/calc_getApplicationVersion.calc:
--------------------------------------------------------------------------------
1 | /*-- Application is Pro, Runtime, or Go --*/
2 |
3 | Let ( [
4 | ~app = Get ( ApplicationVersion )
5 | ] ;
6 | Position ( ~app ; "Pro" ; 1 ; 1 )
7 | //a or Position ( ~app ; "ProAdvanced" ; 1 ; 1 )
8 | or Position ( ~app ; "Runtime" ; 1 ; 1 )
9 | or Position ( ~app ; "Go" ; 1 ; 1 )
10 | )
11 |
12 | /*
13 | Application versions (minus version number):
14 | - Pro // FileMaker Pro
15 | - ProAdvanced // FileMaker Pro Advanced
16 | - Runtime // FileMaker Runtime
17 | - FileMaker Web Publishing // FileMaker Web Client
18 | - Web Publishing Engine // FileMaker Server Web Client
19 | - xDBC // xDBC Client
20 | - Server // FileMaker Server
21 | - Go // FileMaker Go on the iPhone or iPod touch
22 | - Go_iPad // FileMaker Go on the iPad
23 | */
--------------------------------------------------------------------------------
/dev.getScriptName.txt:
--------------------------------------------------------------------------------
1 | Let([
2 | _script_prefix = scriptPrefix;
3 |
4 | _script_list = ScriptNames( Get( FileName ) );
5 | _found_list = list.filterCustom ( _script_list; "BeginsWith"; _script_prefix; False )
6 |
7 | ];
8 | GetValue ( _found_list; 1 )
9 | )
10 |
11 |
12 | /* —————————————————————————————— //
13 | NAME:
14 | dev.getScriptName ( scriptPrefix )
15 |
16 | PURPOSE:
17 | Returns name of script based on prefix
18 |
19 | EXAMPLES:
20 | dev.getScriptName ( "001" ) = "001 Script Template" (if such a script exists)
21 |
22 | DEPENDENCIES:
23 | List.filterCustom()
24 |
25 | HISTORY:
26 | Created: 2010-May-25 16h33 PST — Donovan A. Chandler
27 | */
--------------------------------------------------------------------------------
/dev.layoutNamesPrefixed.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _layouts = LayoutNames( Get( FileName ) )
3 | ];
4 | ListFilterCustom( _layouts; "BeginsWith"; layoutPrefix; 0 )
5 | )
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | LayoutNamesPrefixed ( layoutPrefix )
10 |
11 | PURPOSE:
12 | Returns list of layouts beginning with specified prefix.
13 |
14 | EXAMPLES:
15 |
16 |
17 | HISTORY:
18 | Created: 2010-Aug-11 00h13 PST — Donovan A. Chandler
19 |
20 | DEPENDENCIES:
21 | Custom Functions: list.custom
22 | */
--------------------------------------------------------------------------------
/nav.measureWindow.fmfn:
--------------------------------------------------------------------------------
1 | Let ( [
2 | clear = GetAsBoolean ( clearMeasurements ) ;
3 | $$_window_orig_height = If ( clear ; "" ; Get ( WindowHeight ) ) ;
4 | $$_window_orig_width = If ( clear ; "" ; Get ( WIndowWidth ) ) ;
5 | $$_window_orig_top = If ( clear ; "" ; Get ( WIndowTop ) ) ;
6 | $$_window_orig_left = If ( clear ; "" ; Get ( WindowLeft ) )
7 | ] ;
8 | ""
9 | )
10 |
11 | /* __________________________________________________
12 |
13 | NAME: NavMeasureWindow()
14 | PURPOSE: Measures location and dimensions of current window for use by NavSetWindowSettings()
15 | EXAMPLES:
16 | NavMeasureWindow( ) // sets window measurements to global vars
17 | NavMeasureWindow( False ) // clears global vars
18 | HISTORY:
19 | Created: 2009-08-13 16:02 PT - Donovan Chandler
20 | Modified: 2013-03-06 16:02 PT - Donovan Chandler : reformatted; changed var names; no longer uses Evaluate on boolean input.
21 | */
--------------------------------------------------------------------------------
/plugin.dialogResults.calc:
--------------------------------------------------------------------------------
1 | SDialog_Get ( data_selector ; optional_data )
2 |
3 | /* —————————————————————————————— //
4 | NAME:
5 | DialogResult ( data_selector ; optional_data )
6 |
7 | PURPOSE:
8 | Performs all calls to Simple Dialog function, SDialog_Get().
9 | Contains plug-in references for future changes.
10 |
11 | EXAMPLES:
12 |
13 |
14 | HISTORY:
15 | Created: 2010-May-26 14h53 PST — Donovan A. Chandler
16 | */
--------------------------------------------------------------------------------
/sqlList.calc:
--------------------------------------------------------------------------------
1 | Case (
2 | IsEmpty ( listToDelimit ) ; "" ;
3 | "(" & SqListLoop ( listToDelimit ) & ")"
4 | )
5 |
6 | /* __________________________________________________
7 |
8 | NAME: SqList ( listToDelimit )
9 | PURPOSE: Converts return-delimited list into comma-delimited list of quoted strings.
10 | Useful for IN clauses in SQL statements.
11 | EXAMPLES:
12 | SqList ( "dog¶cat\¶mouse" ) = "('dog','cat¶mouse')"
13 | HISTORY:
14 | Created: 2011-10-26 16:23 PT - Donovan A. Chandler
15 | */
--------------------------------------------------------------------------------
/test.compareFields.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _field_cur = GetFieldName ( Self );
3 | _field_comp = "UNIT_OF_INCIDENT_SELECTED::MANUF_YEAR"
4 | ];
5 | Self ≠ Evaluate ( _field_comp )
6 | )
7 |
8 | /* —————————————————————————————— //
9 | NAME:
10 |
11 |
12 | PURPOSE:
13 |
14 |
15 | EXAMPLES:
16 |
17 |
18 | HISTORY:
19 | Created: 2010-Jun-25 13h02 PST — Donovan A. Chandler
20 | */
--------------------------------------------------------------------------------
/test.sortDisplay.calc:
--------------------------------------------------------------------------------
1 | Let([
2 | _field = fieldName;
3 | _rep = displayFieldRepetition;
4 | _isDescending = If ( _rep = 2; 1; 0 );
5 | _sortedFieldName = UIN_FOCUS::GT_SORT_FIELD_NAME;
6 | _sortedDescending = UIN_FOCUS::GN_SORT_DESCENDING_FLAG;
7 |
8 | _table = ExtractTableName ( _field );
9 | _index = TableIndex( _table );
10 | _sort_field = GetRepetition( _sortedFieldName; _index );
11 | _sort_desc = GetRepetition( _sortedDescending; _index )
12 | ];
13 | Case(
14 | _field = _sort_field and
15 | _sort_desc = GetAsBoolean( _isDescending );
16 | 1
17 | )
18 | )
19 |
20 | /* —————————————————————————————— //
21 | NAME:
22 | test.sortDisplay( fieldName; displayFieldRepetition )
23 |
24 | PURPOSE:
25 | Returns True if specified field is being sorted
26 |
27 | EXAMPLES:
28 | test.sortDisplay(
29 | GetFieldName( ERD_COMPANY::NAME );
30 | 1
31 | ) returns True if sort is by Name ascending
32 |
33 | HISTORY:
34 | Created: 2010-Aug-20 12h49 PST — Donovan A. Chandler
35 | */
--------------------------------------------------------------------------------
/web.dataStore.calc:
--------------------------------------------------------------------------------
1 | "Data:text/html," & ¶ &
2 | "" & ¶ &
3 | "¶"
6 |
7 | /* —————————————————————————————— //
8 | NAME:
9 | WebDataStore ( dataString; backgroundColor )
10 |
11 | PURPOSE:
12 | Stores text in hidden webviewer for retrieval.
13 |
14 | EXAMPLES:
15 | WebDataStore(
16 | #( "TABLE" ; "CONTACT" ) & #( "FILTER_TABLE"; "POPUP" )
17 | "RGB( 249,249,249 )"
18 | )
19 | Creates webviewer with a gray background.
20 |
21 | To Use:
22 | #Value(
23 | GetLayoutObjectAttribute( "webviewer_name" );
24 | "TABLE"
25 | ) = "CONTACT"
26 |
27 | HISTORY:
28 | Created: 2010-Sep-06 10h00 PST — Donovan A. Chandler
29 |
30 | NOTES:
31 | Best practice is to place the webviewer in the bottom-right, or bottom-left corner and on a white background so that it is inconspicuous while loading.
32 | Retrieve dataString using GetLayoutObjectAttribute( "webviewer_name"; "content" ).
33 | Webviewer is hidden using background color.
34 | backgroundColor param can be passed any CSS-valid value, so words like "white" are also supported.
35 | */
--------------------------------------------------------------------------------
/xml.transform.fmfn:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | NAME:
3 | xml.transform( xmlSource; addCharacters )
4 |
5 | PURPOSE:
6 | Adds or removes replacement characters that aid in XML parsing
7 |
8 | HISTORY:
9 | Created 2008.12.16 by DChandler
10 |
11 | INPUT:
12 | xmlSource: Text string in XML format
13 | addCharacters: Boolean - True adds transformation, False removes it
14 |
15 | OUTPUT:
16 | xmlSource with ">" characters replaced with "‡>". This allows tags to be parsed easily with or without the presence of attributes
17 | ---------------------------------------------------------------------------------------*/
18 |
19 | Case(
20 | Evaluate( addCharacters );
21 |
22 | // Add search characters
23 | Substitute( xmlSource; [" "; "‡"]; ["‡>"; ">"]; [">"; "‡>"]; [""; "≤/"] );
24 |
25 | // Remove search characters
26 | Substitute( xmlSource; ["‡>"; ">"]; ["‡"; " "]; ["≤/"; ""] )
27 | )
--------------------------------------------------------------------------------
/xml.verify.fmfn:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------------------
2 | NAME:
3 | xml.verify( xmlResult; useNullValues )
4 |
5 | PURPOSE:
6 | Checks if xml querry returns a valid result (for use with xml.select())
7 |
8 | HISTORY:
9 | Created 2008.12.18 by DChandler
10 |
11 | INPUT:
12 | xmlResult: Results of an xml querry (usually with xml.select())
13 | useNullValues: (Boolean) False = Empty xmlResult counted as error
14 |
15 | OUTPUT:
16 | Returns True if no errors are found in xmlResult
17 |
18 | xml.verify( ""; True ) -> True
19 | xml.verify( ""; False ) -> False
20 | xml.verify( "Error 101: Invalid Path"; False ) -> False
21 | xml.verity( "value"; False ) -> True
22 | ---------------------------------------------------------------------------------------*/
23 |
24 | Let(
25 | [
26 | //xmlResult = xmlResult
27 | //; useNullValues = useNullValues;
28 |
29 | bnError = ( Left( xmlResult; 5 ) = "Error" )
30 | ; bnNull = IsEmpty( xmlResult )
31 | ; bnInvalid = bnError or Case( Evaluate( useNullValues ); bnNull; 0 )
32 | ];
33 | not bnInvalid
34 | )
--------------------------------------------------------------------------------